Right way to instantiate instance-variables in C++ [closed]
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)?
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.
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.
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.
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>)
{
}
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)
{
...
}
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.
精彩评论