2

I want to ask where in C++ is the right place to instantiate a instance-variables? I think it should not be in the class declaration, but otherwise I don`t see any disadvantages apart from poor object-oriented design:

class A{ member m; };

I think it should better be like:

class A{ extern member m; };

But I don`t know how to realize it without a pointer like this:

class A{ member* m };

A::A(){ m = new member; }

Is there a "clean solution" to realize this on the stack (without using pointers)?

Brian Webster
  • 27,545
  • 47
  • 143
  • 218
Dudero
  • 547
  • 6
  • 15

6 Answers6

6

You can use the constructor initialization list to construct all your member variables as you need.

A::A(const member& memberArg)
     : m(memberArg) 
{ }

Look at this for more info.

sergio
  • 67,961
  • 11
  • 98
  • 119
  • you mean `class A{ member m; };` and then `member m;`...`A::A():m(m){}` – Dudero Jul 18 '11 at 16:55
  • 2
    Better make the parameter `const member &`. – Nawaz Jul 18 '11 at 16:55
  • yes, that is what I mean. An instance variable in C++ is exactly that: `class A{ member m; };` – sergio Jul 18 '11 at 16:56
  • @Nawaz: Thanks, Nawaz... – sergio Jul 18 '11 at 16:56
  • Ok thanks, but what if I don`t have a member object for constructor initialization list from higher level - is there a chance to do this within class A (without new/pointer)? – Dudero Jul 18 '11 at 17:02
  • You mean: if your member is, e.g, a `long`? The construction init. list will work equally. In any case, you can also assign in the constructor body: `A::A(const long memberArg) { m = memberArg; }` – sergio Jul 18 '11 at 17:12
4

I think you have a misunderstanding of how objects are instantiated. If all you do is declare a class, no member variables are actually instantiated. It isn't until you construct an instance of that class that its member variables exist.

Here's an example to show when a member object gets instantiated:

class ClassA
{
public:
  ClassA() { std::cout << "Hello!\n"; }
};

class ClassB
{
public:
  ClassA objA;
};

int main()
{
  // do some work
  ClassB objB; // here, a ClassB object is created, and with it its member ClassA object, so "Hello!" is printed
  return 0;
}

As to exactly how you specify what kind of ClassA object to create if its constructor requires arguments, the other answers do a fine job explaining it.

Sean
  • 2,797
  • 22
  • 30
  • Thank you Sean, you are right, I had a misunderstanding of how objects in C++ are instantiated. – Dudero Jul 19 '11 at 08:00
1

I think it should not be in the class declaration, but otherwise I don`t see any disadvantages apart from poor object-oriented design:

class A{ member m; };

What in your mind makes this poor OO design? This is the preferred mechanism in C++.

I think it should better be like:

class A{ extern member m; };

This isn't valid code. Qualifying member data with a storage class specification such as extern is illegal.

But I don`t know how to realize it without a pointer like this:

class A{ member* m; };
A::A(){ m = new member; }

That will work, but why do that? It looks to me like you are trying to import a Java POV into C++. Everything is allocated, and everything is a reference in Java. In many (most!) cases there is no reason to allocate data members in C++. All it does is add an unneeded indirection and add a place where memory can leak.

Community
  • 1
  • 1
David Hammen
  • 30,597
  • 8
  • 54
  • 98
0

You want to use member initializers: they are the only way to initialize class members that have a constructor that requires parameters, and the cleanest way to initialize other class members.

If you have class A and a member m with a constructor:

class A { member m; }

You want

class A { member m; A(); }

A::A()
: m(<constructor params>)
{
}
antlersoft
  • 14,223
  • 3
  • 28
  • 52
0

You would declare your instance variables in your .h file:

A.h

class A {

   public:
      A();
   private:
      int value;
      double someOtherValue;
}

You can instantiate them in your .cpp file like so:

A.cpp

A::A(): value(5), someOtherValue(10.0)
{
   ...
}
Manny D
  • 18,454
  • 2
  • 26
  • 31
0

If the member object is to be totally controlled by the enclosing A object, your first example is the proper way to do it. It does have the downside of requiring a complete definition of member at the point where A is defined.

You could check out the pimpl idiom to reduce coupling, but that still requires the object to be heap-based and not stack-based.

Community
  • 1
  • 1
Mark Ransom
  • 271,357
  • 39
  • 345
  • 578