在学习C ++(和Direct3D,但前一段时间)时,让我感到困惑的一件事就是你应该在类中使用指针成员。例如,我可以使用非指针声明:
private:
SomeClass instance_;
或者我可以使用指针声明
private:
Someclass * instance_
然后在构造函数中使用new()。
据我所知,如果SomeClass可以从另一个类派生,一个COM对象或者是一个ABC,那么它应该是一个指针。是否还有其他我应该注意的指导原则?
答案 0 :(得分: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!
};
c)可以随时删除指针 - 这样您就可以更好地控制实时时间并重新创建对象 - 例如,如果发生故障。
答案 1 :(得分:17)
3DH概述了使用指针的优点:延迟初始化,减少标头依赖性,以及控制对象的生命周期。
这也是缺点。如果有指针数据成员,则可能必须编写自己的复制构造函数和赋值运算符,以确保正确创建对象的副本。当然,您还必须记住在析构函数中删除该对象。此外,如果将指针数据成员添加到现有类,则必须记住更新复制构造函数和operator =。简而言之,拥有指针数据成员对您来说更有用。
另一个缺点实际上是控制指针所指向的对象的生命周期的另一面。当对象被销毁时,非指针数据成员会自动销毁,这意味着只要对象存在,您就可以始终确保它们存在。使用指针,您必须检查它是否为nullptr
,这意味着只要不指向任何内容,您必须确保将其设置为nullptr
。必须处理所有这些可能很容易导致错误。
最后,访问非指针成员可能会更快,因为它们在内存中是连续的。另一方面,访问指向堆上分配的对象的指针数据成员可能会导致缓存未命中,从而使其变慢。
您的问题没有单一的答案。您必须查看您的设计,并确定指针数据成员的优势是否超过额外的头痛。如果减少编译时间和标头依赖性很重要,请使用pimpl idiom。如果在某些情况下您的对象可能不需要您的数据成员,请使用指针,并在需要时分配它。如果这些听起来不是令人信服的理由,并且您不想做额外的工作,那么请不要使用指针。
答案 2 :(得分:12)
如果可以,可以在免费商店中将其分配到堆栈中。这里有一个similar question,您可以找到所有“为什么”。
你在游戏和东西中看到很多指针使用的原因是因为DirectX是一个COM接口,而且诚实地说,大多数游戏程序员来自当天不是真正的C ++程序员,他们是C-with - 类程序员,在C指针使用中很常见。
答案 3 :(得分:3)
使用指针的另一个原因是动态绑定。如果你有一个带有虚方法和一些派生类的基类,你只能使用指针获得动态绑定。