我想问一下C ++中哪里是实例化实例变量的正确位置?我认为它不应该在课堂宣言中,但除了面向对象设计不佳之外我不会看到任何缺点:
class A{ member m; };
我认为应该更好:
class A{ extern member m; };
但我不知道如何在没有这样的指针的情况下实现它:
class A{ member* m };
A::A(){ m = new member; }
是否有一个“干净的解决方案”在堆栈上实现这一点(不使用指针)?
答案 0 :(得分:6)
答案 1 :(得分:3)
我认为你对如何实例化对象有误解。如果您所做的只是声明一个类,则实际上不会实例化任何成员变量。直到你构造该类的实例才存在其成员变量。
这是一个显示成员对象实例化时间的示例:
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;
}
至于如何指定在构造函数需要参数时要创建哪种ClassA对象,其他答案可以很好地解释它。
答案 2 :(得分:1)
我认为它不应该在课堂宣言中,但除了面向对象设计不佳之外我不会看到任何缺点:
class A{ member m; };
你的想法是什么让这个糟糕的OO设计?这是C ++中的首选机制。
我认为应该更好:
class A{ extern member m; };
这不是有效的代码。具有存储类规范(例如extern
)的合格成员数据是非法的。
但我不知道如何在没有这样的指针的情况下实现它:
class A{ member* m; };
A::A(){ m = new member; }
那会有效,但为什么呢?在我看来,您正在尝试将Java POV导入C ++。一切都已分配,一切都是Java的参考。在许多(大多数!)情况下,没有理由在C ++中分配数据成员。它所做的只是添加一个不需要的间接,并添加一个内存可能泄漏的地方。
答案 3 :(得分:0)
您想要使用成员初始值设定项:它们是初始化具有需要参数的构造函数的类成员的唯一方法,也是初始化其他类成员的最简洁方法。
如果你有A类和一个带有构造函数的成员m:
class A { member m; }
你想要
class A { member m; A(); }
A::A()
: m(<constructor params>)
{
}
答案 4 :(得分:0)
您可以在.h
文件中声明实例变量:
<强> A.H 强>
class A {
public:
A();
private:
int value;
double someOtherValue;
}
您可以在.cpp文件中实例化它们,如下所示:
<强> A.cpp 强>
A::A(): value(5), someOtherValue(10.0)
{
...
}
答案 5 :(得分:0)
如果成员对象完全由封闭的A
对象控制,那么您的第一个示例是正确的方法。它确实有一个缺点,即在定义member
时要求A
的完整定义。
您可以查看pimpl idiom以减少耦合,但仍然需要对象基于堆而不是基于堆栈。