【问题标题】:Differences between declaring a variable in a header file as pointer and non-pointer将头文件中的变量声明为指针和非指针之间的区别
【发布时间】:2014-08-07 09:11:21
【问题描述】:

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

例如

class MyClass {

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

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

优点:

  • 延迟实例化(不立即创建对象)
  • 变量位于比堆栈大得多的堆上
  • 不仅可以使用默认构造函数

缺点:

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

还有什么要说的?

【问题讨论】:

  • 另一个问题是,如果不是指针,您将需要在标题中完整定义 MyOtherClass,而如果它是指针,您可以转发声明该类并将标题包含在 cpp 中
  • 您可以通过初始化列表使用默认构造函数以外的其他构造函数。您可以使用智能指针来摆脱析构函数,尽管编写良好的类实现不需要这些。
  • 变量在堆上?哪个变量?您没有显示任何东西在“堆”上分配的东西。你所拥有的只是一个数据成员,它是一个指针,它可以指向任何东西(或什么都没有)。
  • 在您的优势列表中,第二个和第三个项目符号不正确。

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


【解决方案1】:

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

MyClass 有一个moc2 并使用moc

在做出决定时要考虑类的设计以及它们之间的交互方式,而不是基于指针与对象的争论。每个MyClass 对象都有自己的moc2 成员,但多个MyClass 对象可以在它们之间共享一个moc

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

优点:

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

缺点:

  • 必须在析构函数中手动删除(顺便说一句。这样的非指针变量何时被销毁?程序何时结束?) - 仅当MyClass 拥有该成员时 - 它可能是指向某个对象的指针在别处创建,因此MyClass 不负责管理它。

【讨论】:

  • 这里只是补充一点:如果MyClass是所有者,您可以使用std::unique_ptr<MyOtherClass>来避免手动销毁对象。
【解决方案2】:

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

优点: - 延迟实例化(不立即创建对象) - 类的定义不需要可见,前向声明就够了

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

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

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

最后进入你的名单:

变量存在于比栈大得多的堆上

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

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

完全不正确,初始化列表中你可以为成员构造函数指定任何参数。

【讨论】:

    【解决方案3】:

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

    至于何时使用,这已经在 SO here 讨论过

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

    【讨论】:

      猜你喜欢
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 2016-05-03
      • 2013-07-12
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多