【发布时间】:2012-03-22 17:13:32
【问题描述】:
我需要在 c++ linux 中澄清一下。
我有class C1 和另一个class C2。 C1 将有 C2 的引用。
class C1
{
C2 &obj ;
}
我在这里考虑两个选择,
- 直接持有
C2的引用为C2 &obj; - 创建
C2的指针,为c2* obj;
哪个好?有什么区别呢?什么时候选择?
【问题讨论】:
标签: c++
我需要在 c++ linux 中澄清一下。
我有class C1 和另一个class C2。 C1 将有 C2 的引用。
class C1
{
C2 &obj ;
}
我在这里考虑两个选择,
C2的引用为C2 &obj;
C2的指针,为c2* obj;
哪个好?有什么区别呢?什么时候选择?
【问题讨论】:
标签: c++
两者都不好。如果你有任何指针 或 引用成员变量指向在你的类之外分配的东西,这很可能意味着程序设计存在某种缺陷。
我可以提出一个合理的情况,即当您拥有某种特殊的外部垃圾收集器功能时。 (例如 C++ Builder 在堆上自动分配/释放 VCL 组件。)
另一种情况是它可能有效,即当您使用 C++ 类模拟 C 结构时,或者在另一个类中编写私有类时。
但最有可能的是,需要指出课堂之外的东西来自有缺陷的程序设计。我会三思而后行为什么我的代码需要这样做,并且至少尝试为指针添加尽可能多的 const 正确性,即const *c2 const obj;
如果你有这样特殊的成员指针,你很可能还必须为你的类手动编写一个复制构造函数、赋值运算符和析构函数。
编辑:为什么这是不好的做法的基本原理是称为private encapsulation 的概念,它是称为object-oriented design 的程序设计概念的基石之一。
【讨论】:
你要使用哪一个,取决于你到底需要什么。
例如,如果您需要某种依赖注入,则可以使用引用成员变量。即使这样,您也可以使用指针。但是,请记住,具有引用成员的类通常应该是不可复制的。
在大多数情况下,您应该使用指针或值成员变量。
【讨论】:
指针对引用有两个主要优点。指针可以为空并且可以移动指针(例如使用 ++ 运算符)。 搬家对你没有帮助。 如果在实例化 C1 时您的类 C2 未知,那么您应该使用指针,因为您无法初始化引用,但可以将指针初始化为 null。
就像 Als 所说,我还建议在 C2 实例可能发生变化时使用指针。在这种情况下您可以使用引用,但我认为指针是一种“更清洁”的解决方案。
【讨论】:
尽可能避免使用引用成员。
此处适用与引用和指针相同的差异,
如果您有一个引用成员,那么它必须在创建类对象时进行初始化,您不能像指针成员那样进行延迟初始化,因为引用不能为 NULL 并且不能重新安装,而可以在需要时使指针成员懒惰地指向C2 实例。
另外,请注意还有其他副作用,一旦你有一个引用成员,编译器将不会生成复制赋值运算符(=)&你必须自己提供一个,确定什么是复杂的在这种情况下,您的 = 运营商应采取的行动。
对于大多数实际目的(除非您真的担心由于 C2 大小而导致的高内存使用),只需将 C2 的实例作为 C1 的成员就足够了,而不是指针或引用成员,这可以为您节省很多担心引用/指针成员带来的其他问题,尽管以额外的内存使用为代价。
如果必须,请使用指针,确保使用智能指针而不是原始指针,这样使用指针会让您的生活更轻松。
【讨论】: