Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I write classes? C++

Hey.. I don't really get them. I read a tutorial about classes in C++, and I don't get a few things: In every example and tutorial that I've seen, functions are never written inside the class! For example, why write a class like this:

#include <iostream>

using namespace std;

class test
{
    private:
        int x, y;
    public:
        test (int, int);
        int tester () {return x + y; }
};

test::test (int a, int b)
{
    x = a;
    y = b;
}

int main()
{
    test atest (3, 2);
    test atest2 (2, 6);

    cout << "test1: " << atest.tester() << endl;
    cout << "test2: " << atest2.tester() << endl;

    return 0;
}

or like this:

#include <iostream>

using namespace std;

class test
{
    private:
        int x, y;
    public:
        void set_values (int,int);
        int testfunc () {return x + y; }
};

void test::set_values (int a, int b)
{
    x = a;
    y = b;
}

int main()
{
    test tester;

    tester.set_values (3, 2);

    cout << "test1: " << tester.testfunc() << endl;

    return 0;
}

instead of simply like this:

#include <iostream>

using namespace std;

class test
{
    public:
        int tester (int x, int y) { return x + y; }
};

int main()
{
    test atest;

    cout << atest.tester(3, 2) << endl;

    return 0;
}

Honestly, I just don't get it!

Why do I need private members??

When and how should I use destructors?

How should I generally write my classes?

I'm very confused here and I really need somebody to clear up things for me... thanks

like image 431
Lockhead Avatar asked Dec 08 '25 06:12

Lockhead


2 Answers

As Greg says you really need to read a book.

How should I generally write my classes?
Classes let you combine data and functions that act on them into one thing.

Why do I need private members??
Private members can only be accessed by functions in your class, this lets you control how data is stored in the class without the user of the class being able to do things you don't expect.

When and how should I use destructors?
When you have something that needs to be cleaned up when you object is no longer needed, a file closed or memory released.

like image 193
Martin Beckett Avatar answered Dec 09 '25 19:12

Martin Beckett


The example plausibly separates out the setting and retrieving of values because there's more in-between those than you see in the given main function. If there wasn't, you're completely right that you should combine them, and even eliminate the class in favor of a free function.

For example, the code could look something like:

void example(Test obj) {
  if (something) {
    process(obj.tester());
  }
}

int main() {
  int x, y;  // Imagine these are assigned to user input.
  Test obj (x, y);
  example(obj);  // Obj.tester may or may not be used.  If the x + y was not
  // separated, then you couldn't "maybe use" it.
  return 0;
}

Why do I need private members?

You don't. They're more documentation than anything else. Accessibility (public/protected/private) is documentation which is checked by the compiler, however. This check is helpful mostly in order to encapsulate values, but encapsulation is much, much more than just marking something as non-public. For example, if you (from a public method) return a reference to a non-public data member, you've tied the implementation of that member to the class' public interface.

When and how should I use destructors?

When you need special destruction logic. Read about the Rule of Three. Write them as if they were a class method named "~" plus the class name, taking no parameters and omit a return type (even void), similarly as for ctors.

How should I generally write my classes?

You don't have to define the methods outside of the class. In fact, implement all methods inside the class to start out with, then move the methods out as there is a need. This is much harder to screw up while you learn the important basics of the language, and much more convenient for the types of classes you'll write initially. Use ctor initializers when they are just as feasible as assignment within the ctor body.

struct Test {
  Test(int x, int y)  // Use the same names rather than inventing 'a' and 'b'.
  : _x (x), _y (y)
  {}

  int tester() const { return _x + _y; }
  // Move outside the class when needed, if at all -- and it won't be needed
  // for a function like this.
  // Because this doesn't modify anything, it's suitable to be const, which
  // means it can be called on a const Test object.

  int _x, _y;
  // Technically public, but with a "non-public name".  Mark private as you
  // wish, or as the design settles down.
};

Note I've used "struct" to declare this class instead of "class". The result is identical, except I get to skip "public" on any base classes (there are none here, but bases are more often public than not) and the default member accessibility is "public" too: this results in shorter and slightly more clear code.

like image 26
Fred Nurk Avatar answered Dec 09 '25 18:12

Fred Nurk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!