这是一个简单的例子来说明这个问题:
class A {};
class B
{
B(A& a) : a(a) {}
A& a;
};
class C
{
C() : b(a) {}
A a;
B b;
};
So B
负责更新一部分C
。我通过 lint 运行了代码,它抱怨引用成员:皮棉#1725 http://gimpel-online.com/MsgRef.html#1725。
这讨论了如何处理默认复制和赋值,这很公平,但是默认复制和赋值对于指针来说也很糟糕,因此几乎没有什么优势。
我总是尝试尽可能使用引用,因为裸指针不确定谁负责删除该指针。我更喜欢按值嵌入对象,但如果我需要指针,我会使用std::auto_ptr
作为拥有指针的类的数据成员,并将对象作为引用传递。
当指针可能为空或可能更改时,我通常只会使用指针作为数据成员。对于数据成员,还有其他原因更喜欢使用指针而不是引用吗?
由于引用一旦初始化就不应更改,因此包含引用的对象不应该是可分配的,这是真的吗?
我自己的经验法则:
-
当您希望对象的生命周期依赖于其他对象的生命周期时,请使用引用成员:这是一种明确的方式,表明您不允许对象在没有另一个类的有效实例的情况下存活 - 因为没有赋值并且有义务通过构造函数获取引用初始化。这是设计类的好方法,无需假设它的实例是否是另一个类的成员。你只是假设他们的生活与其他实例直接相关。它允许您稍后更改使用类实例的方式(使用 new、作为本地实例、作为类成员、由管理器中的内存池生成等)
-
其他情况使用指针:当您希望稍后更改成员时,请使用指针或 const 指针以确保只读取所指向的实例。如果该类型应该是可复制的,则无论如何都不能使用引用。有时,您还需要在特殊函数调用(例如 init())之后初始化成员,然后您别无选择,只能使用指针。但是:在所有成员函数中使用断言可以快速检测错误的指针状态!
-
如果您希望对象生存期依赖于外部对象的生存期,并且还需要该类型是可复制的,则在构造函数中使用指针成员但引用参数这样,您就可以在构造中指示该对象的生命周期取决于参数的生命周期,但实现使用指针仍然是可复制的。只要这些成员仅通过复制进行更改,并且您的类型没有默认构造函数,则该类型应该满足这两个目标。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)