4

考虑以下代码:

#include <iostream>

struct B {
    void bar() {
        std::cout << "I feel used\n";
    }
};

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其成员函数中的状态。

我的问题:

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

3 回答 3

3

这样做是个好习惯吗?

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

有什么缺点?

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

有什么替代方案?

std::shared_ptr如果它是外部拥有的。否则,复制或合成可以降低复杂性。

class C { // OK - b obviously outlives a
 C() : b(), a(b) {}
 B b;
 A a;
};
于 2013-07-08T21:35:39.260 回答
1

在一个简单的程序中,你所做的很好。

我认为您会发现在具有任何复杂性的程序(IE 不是简单的语言示例)中,您最终将需要一个指针(或者更好的是 shared_ptr),而不是在对象的生命周期内保持引用。

如果您可以在整个时间内保持引用,那么您可能应该使用您完全拥有的对象,这是很好的机会。为什么?当该引用超出范围并被销毁时,您将怎么做?

于 2013-07-08T21:35:31.527 回答
1

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

于 2013-07-08T21:40:46.353 回答