鉴于“A”类存在并且是正确的。使用“A”引用而不是类“B”中的指针会产生什么负面结果。那就是:
// In Declaration File
class A;
class B
{
public:
B();
~B();
private:
A& a;
};
// In Definition File
B::B(): a(* new A())
{}
B::~B()
{
delete &a;
}
为了进一步纠正“B”而省略了额外的代码,例如复制构造函数和赋值运算符,只是想展示问题的概念。
答案 0 :(得分:4)
当前的局限性是:
A
,但在a
生命周期内无法重新分配或重新分配B
。a
绝不能是0
。因此:
B
不应该是可复制的,除非您教导A
及其子类型正确克隆。B
将不是作为集合类型元素的良好候选者。 B
s的向量可能最容易实现为std::vector<B*>
,这可能会引入更多复杂性(或简化,取决于您的设计)。根据您的需要,这些可能是好事。
注意事项:
a
是可分配的,并且B
内可以进行分配。答案 1 :(得分:2)
您无法在事后更改a所引用的对象,例如在任职。此外,它使你的类型非POD(无论如何,由于私有数据成员,给定的类型将是非POD,但在某些情况下它可能很重要。)
但主要的缺点可能是它可能会使读者感到困惑。
答案 2 :(得分:1)
当然,通过向类B
添加引用成员意味着编译器不能再生成隐式的默认和复制构造函数以及赋值运算符;并且手动编写的赋值运算符都不能重新分配a
。
除了delete &a
可能看起来奇怪的事实之外,我认为不会有负面结果。 new
创建对象的事实在某种程度上通过将结果绑定到引用而丢失了,这可能只是因为它的生命周期必须由B
控制这一事实并不明确。< / p>
答案 3 :(得分:1)
如果您使用参考:
您可能会考虑使用某种智能指针(std :: unique_ptr,std :: shared_ptr等)。这具有为您自动删除对象的额外好处。
答案 4 :(得分:0)
对动态分配对象的引用违反了最少意外的原则;也就是说,没有人通常会期望您编写的代码。总的来说,这将使维护成本在未来更高。
答案 5 :(得分:0)
引用的问题是,它看起来像是同一变量的别名或其他名称,但是您查看的是内部生成的机器代码,它们使用常量指针进行操作,这可能是性能问题,因为您可能会认为进行可变算术运算的代码,但是在汇编代码级别,它们正在操纵在代码级别可能无法实现的指针。 您可能不想在需要快速整数或浮点运算的地方使用指针操作。