将头文件中的变量声明为指针和非指针之间的差异

时间:2014-08-07 09:11:21

标签: c++ variables pointers header-files declaration

将头文件中的变量声明为指针或非指针之间有什么区别?我不确定我是否正确理解这些差异。

E.g。

class MyClass {

private:
    MyOtherClass* moc; // pointer
    MyOtherClass moc2; // no pointer
}

到目前为止,在将变量声明为指针时,我已经提出了以下优点/缺点。

优点:

  • 懒惰实例化(不立即创建对象)
  • 变量存在于堆上,远远大于堆栈
  • 不仅可以使用默认构造函数

缺点:

  • 必须在析构函数中手动删除(顺便说一句。何时这样的非指针变量被破坏?当程序结束时?)

还有什么可说的?

3 个答案:

答案 0 :(得分:5)

拥有一个对象表示所有权。它的组成。指针可以表示所有权,但大多数时候它们意味着聚合

即。 MyClassmoc2并使用moc

决定考虑类的设计以及它们如何相互作用,而不是基于指针与对象的争论。每个MyClass对象都有自己的moc2成员,但多个MyClass对象可以在它们之间共享moc

关于您提出的优点/缺点:

优点:

  • 懒惰实例化(没有立即创建对象) - 指针本身被初始化 - 记住你的成员是一个指针而不是一个对象。但我会告诉你,你有时需要这个,虽然它大部分时间都是代码味道。
  • 变量存在于堆上,远远大于堆栈 - 不一定 - 您也可以拥有指向基于堆栈的变量的指针。此外,如果在堆上分配了MyClass对象,moc2也是如此。
  • 不仅可以使用默认构造函数 - 非问题,您可以在两种情况下使用任何构造函数(请参阅initialization-lists)。

缺点:

  • 必须在析构函数中手动删除(顺便说一句。什么时候这样的非指针变量被破坏?当程序结束?) - 只有MyClass拥有该成员 - 它可能是一个指针在其他地方创建了一些对象,因此MyClass不负责管理它。

答案 1 :(得分:1)

一些优点/缺点需要纠正,所以你去:

优点: - 懒惰实例化(没有立即创建对象) - 不需要看到类的定义,前向声明就足够了

缺点: - 必须在析构函数中手动删除 - 您需要手动声明所有复制构造函数和赋值运算符 - 更复杂的访问权限(->而不是.

一些替代方案:智能指针(std :: unique_ptr)。具有原始指针的所有优点,并且在析构函数中不需要显式删除,通常更安全。除非确实需要,否则永远不应该使用原始指针,因此如果您需要指针的优点,请使用智能指针。

如果你想要延迟初始化,可以使用boost::optional

最后对你的清单评论:

  

变量存在于堆上,远远大于堆栈

不完全正确。如果它是一个指针,并且使用new创建了对象,则该对象将在堆中。否则它不一定会在堆栈上。它将是父对象的位置。如果父对象在堆上,那么封闭的对象 - 从它开始的一部分 - 也在堆上。

  

不仅可以使用默认构造函数

根本不是真的,初始化列表可以为成员构造函数指定任何参数。

答案 2 :(得分:0)

拥有指针并不会自动意味着您将拥有动态分配的变量。你也可以指向自动变量或静态变量(我不是说这是常见的或鼓励的,我只是技术性的)。使用指针可以选择动态分配变量,但缺点是你必须自己管理内存,(参见herehere)。

至于何时使用,已在SO here

上讨论过

想到的一个区别在于标题包含。当您有一个指向实例的指针作为成员时,您可以转发声明该类型,而按值包含它意味着您必须包含标题,这会减慢构建时间。