作为类成员持有对外部对象的引用的优点/缺点



考虑以下代码:

#include <iostream>
struct B {
    void bar() {
        std::cout << "I feel usedn";
    }
};
struct A {
    B& b;
    A(B& b_) : b(b_) {} // take and keep a reference to the object passed in
    void foo() {
        b.bar(); // potentially change the state of b
    }
};
int main() {
    B b;
    A a(b);
    a.foo(); 
}

A的构造函数以对b的引用为参数,A通过引用改变b在其成员函数中的状态。

我的问题:

  • 这样做被认为是好的做法吗
  • 优点/缺点是什么
  • 有什么替代方案

这样做是个好做法吗?

可能非常危险。你需要确保B的寿命比引用B的A长。有时,使用OP中所示的引用是非常明智的。

缺点是什么?

在某些情况下,确保B的寿命比A长可能非常棘手,如果你引用参数而不是复制它,可能会让客户感到惊讶

有什么替代方案?

std::shared_ptr(如果为外部所有)。否则,复制或合成可以降低复杂性。

class C { // OK - b obviously outlives a
 C() : b(), a(b) {}
 B b;
 A a;
};

在一个琐碎的程序中,您所做的一切都很好。

我想你会发现,在任何复杂的程序中(例如,那些不是简单语言示例的程序),你最终都需要一个指针(或者更好的是共享ptr),而不是保留对象生命周期的引用。

很有可能,如果你能一直保留一个引用,那么你可能应该使用一个你完全拥有的对象。为什么?当引用超出范围并被销毁时,你会怎么办?

您在这里描述的内容与C++(或其他语言)的设计而非技术方面有着更紧密的关系,它在UML中被称为dependency。这是一种常见的做法,就像任何其他技术一样,在使用之前都应该进行适当的分析,以了解它是否真的适合你的问题的解决方案。您可以在此处找到更多详细信息和用法示例。

最新更新