C++ - 我什么时候应该在类中使用指针成员

Ext*_*kun 21 c++ pointers

在学习C++(和Direct3D,但前一段时间)时,让我感到困惑的一件事就是你应该在类中使用指针成员.例如,我可以使用非指针声明:

private:
    SomeClass instance_;
Run Code Online (Sandbox Code Playgroud)

或者我可以使用指针声明

private:
   Someclass * instance_
Run Code Online (Sandbox Code Playgroud)

然后在构造函数中使用new().

我明白,如果SomeClass可以从另一个类派生,COM对象或是ABC,那么它应该是一个指针.我还应该注意其他任何指导方针吗?

3DH*_*3DH 21

指针具有以下优点:

a)您可以进行延迟初始化,这意味着只在第一次实际使用之前初始化/创建对象.

b)设计:如果你使用指针作为外部类类型的成员,你可以在你的类上面放置一个前向声明,因此不需要在你的标题中包含这些类型的标题 - 而不是你包括第三个.cpp中的派对标题 - 这有利于减少编译时间并通过包含太多其他标题来防止副作用.

class ExtCamera;  // forward declaration to external class type in "ExtCamera.h"

class MyCamera {
public: 
  MyCamera() : m_pCamera(0) { }

  void init(const ExtCamera &cam);

private:
   ExtCamera  *m_pCamera;   // do not use it in inline code inside header!
};
Run Code Online (Sandbox Code Playgroud)

c)可以随时删除指针 - 这样您就可以更好地控制实时时间并重新创建对象 - 例如在发生故障时.

  • 转发声明_do_为引用工作. (4认同)
  • 对于延迟初始化,我建议尽可能使用`boost :: optional`.它比指针更安全,因为你无法对其进行算术运算. (3认同)
  • 转发声明*应*用于参考. (2认同)
  • 你仍然可以使用前向声明和引用 - 只要你的头文件中没有任何代码,_uses_(访问)引用 - 所以任何声明都有效,但不是内联代码. (2认同)

Dim*_*ima 18

3DH概述了使用指针的优点:延迟初始化,减少头依赖性以及控制对象的生命周期.

这也是缺点.如果有指针数据成员,则可能必须编写自己的复制构造函数和赋值运算符,以确保正确创建对象的副本.当然,您还必须记住在析构函数中删除该对象.此外,如果将指针数据成员添加到现有类,则必须记住更新复制构造函数和operator =.简而言之,拥有指针数据成员对您来说更有用.

另一个缺点实际上是控制指针所指向的对象的生命周期的另一面.当对象被销毁时,非指针数据成员会自动销毁,这意味着只要对象存在,您就可以始终确保它们存在.使用指针,您必须检查它是否存在nullptr,这意味着您必须确保在nullptr没有指向任何内容时将其设置为.必须处理所有这些可能很容易导致错误.

最后,访问非指针成员可能会更快,因为它们在内存中是连续的.另一方面,访问指向堆上分配的对象的指针数据成员可能导致高速缓存未命中,使其变慢.

你的问题没有一个单一的答案.您必须查看您的设计,并确定指针数据成员的优势是否超过额外的头痛.如果减少编译时间和标头依赖性很重要,请使用pimpl习惯用法.如果在某些情况下您的对象可能不需要您的数据成员,请使用指针,并在需要时分配它.如果这些听起来不是令人信服的理由,并且您不想做额外的工作,那么请不要使用指针.


GMa*_*ckG 12

如果可以的话,可以在免费商店中将其分配到堆栈中.这里有一个类似的问题,你会发现所有"为什么".

你在游戏和东西中看到很多指针使用的原因是因为DirectX是一个COM界面,而且诚实地说,大多数游戏程序员来自当天不是真正的C++程序员,他们是C-with-classes程序员,在C指针使用中很常见.