将头文件中的变量声明为指针或非指针之间有什么区别?我不确定我是否正确理解这些差异。
E.g。
class MyClass {
private:
MyOtherClass* moc; // pointer
MyOtherClass moc2; // no pointer
}
到目前为止,在将变量声明为指针时,我已经提出了以下优点/缺点。
优点:
缺点:
还有什么可说的?
答案 0 :(得分:5)
拥有一个对象表示所有权。它的组成。指针可以表示所有权,但大多数时候它们意味着聚合。
即。 MyClass
有moc2
并使用moc
。
决定考虑类的设计以及它们如何相互作用,而不是基于指针与对象的争论。每个MyClass
对象都有自己的moc2
成员,但多个MyClass
对象可以在它们之间共享moc
。
关于您提出的优点/缺点:
优点:
MyClass
对象,moc2
也是如此。 缺点:
MyClass
拥有该成员 - 它可能是一个指针在其他地方创建了一些对象,因此MyClass
不负责管理它。 答案 1 :(得分:1)
一些优点/缺点需要纠正,所以你去:
优点: - 懒惰实例化(没有立即创建对象) - 不需要看到类的定义,前向声明就足够了
缺点:
- 必须在析构函数中手动删除
- 您需要手动声明所有复制构造函数和赋值运算符
- 更复杂的访问权限(->
而不是.
)
一些替代方案:智能指针(std :: unique_ptr)。具有原始指针的所有优点,并且在析构函数中不需要显式删除,通常更安全。除非确实需要,否则永远不应该使用原始指针,因此如果您需要指针的优点,请使用智能指针。
如果你想要延迟初始化,可以使用boost::optional
。
最后对你的清单评论:
变量存在于堆上,远远大于堆栈
不完全正确。如果它是一个指针,并且使用new创建了对象,则该对象将在堆中。否则它不一定会在堆栈上。它将是父对象的位置。如果父对象在堆上,那么封闭的对象 - 从它开始的一部分 - 也在堆上。
不仅可以使用默认构造函数
根本不是真的,初始化列表可以为成员构造函数指定任何参数。
答案 2 :(得分:0)