Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;-什么时候应该在类中使用指针成员 < >在学习C++的时候,我一直困惑的一件事(和Direct3D,但在前一段时间)是当你在一个类中使用指针成员时。例如,我可以使用非指针声明: private: SomeClass instance_;_C++_Pointers - Fatal编程技术网

C++;-什么时候应该在类中使用指针成员 < >在学习C++的时候,我一直困惑的一件事(和Direct3D,但在前一段时间)是当你在一个类中使用指针成员时。例如,我可以使用非指针声明: private: SomeClass instance_;

C++;-什么时候应该在类中使用指针成员 < >在学习C++的时候,我一直困惑的一件事(和Direct3D,但在前一段时间)是当你在一个类中使用指针成员时。例如,我可以使用非指针声明: private: SomeClass instance_;,c++,pointers,C++,Pointers,或者我可以使用指针声明 private: Someclass * instance_ 然后在构造函数中对其使用new() 我理解,如果某个类可以从另一个类派生,一个COM对象,或者是一个ABC,那么它应该是一个指针。有没有其他我应该知道的指导原则?如果可以,在堆栈上分配,如果必须,从免费商店分配。这里有一个网站,你可以找到所有的“为什么” 你在游戏和东西上看到很多指针用法的原因是因为DirectX是一个COM接口,而且老实说,大多数的游戏程序员不是真正的C++程序员,他们是C类程序员,C

或者我可以使用指针声明

private:
   Someclass * instance_
然后在构造函数中对其使用new()


我理解,如果某个类可以从另一个类派生,一个COM对象,或者是一个ABC,那么它应该是一个指针。有没有其他我应该知道的指导原则?

如果可以,在堆栈上分配,如果必须,从免费商店分配。这里有一个网站,你可以找到所有的“为什么”


你在游戏和东西上看到很多指针用法的原因是因为DirectX是一个COM接口,而且老实说,大多数的游戏程序员不是真正的C++程序员,他们是C类程序员,C指针用法很常见。 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) 指针可以随时删除—这样您就可以更好地控制livetime并可以重新创建对象—例如在出现故障的情况下。

使用指针的好处可以通过3DH来概括:延迟初始化、减少标头依赖性以及控制对象的生存期

这些都是缺点。当您有一个指针数据成员时,您可能需要编写自己的复制构造函数和赋值运算符,以确保正确创建对象的副本。当然,您还必须记住删除析构函数中的对象。此外,如果向现有类添加指针数据成员,则必须记住更新复制构造函数和运算符=。简而言之,拥有一个指针数据成员对您来说是更多的工作

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

最后,访问非指针成员可能更快,因为它们在内存中是连续的。另一方面,访问指向堆上分配的对象的指针数据成员可能会导致缓存未命中,从而降低缓存速度

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

如果懒惰初始化和头相关的减少是重要的,那么你应该首先考虑使用一个智能指针,比如<代码> STD::UnQuyPPTR <代码>或<代码> STD::SysDypPTR ,而不是原始指针。智能指针使您免于使用上述原始指针的许多麻烦

当然,还有一些警告
std::unique_ptr
会在其自身之后进行清理,因此不需要添加或修改类的析构函数。但是,它是不可复制的,因此使用唯一指针作为数据成员也会使类不可复制


使用
std::shared_ptr
,您不必担心析构函数、复制或赋值。但是,共享指针会对引用计数造成性能损失。

使用指针的另一个原因是动态绑定。如果您有一个带有虚拟方法的基类和一些派生类,则只能使用指针获取动态绑定。

对于延迟初始化,我建议尽可能使用
boost::optional
。它比指针更安全,因为你不能在上面做算术运算。但是很多人(像我一样)不使用Boost——所以这是一种非常平台和框架独立的方式;-)。。。例如,我只使用Qt:-)但是那些不使用
boost
的人应该:)@Extrakun,确保你没有试图访问该头文件中任何地方的QPoint的任何成员。你仍然可以使用前向声明和引用-只要你的头中没有任何代码,它使用(访问)引用-所以任何声明都可以工作,但内联代码不行。这不太正确-可以使用引用进行动态绑定。