C++循环依赖:构造函数应该是什么样子?

C++循环依赖:构造函数应该是什么样子?,c++,circular-dependency,C++,Circular Dependency,我通读了很多循环依赖性主题,但它们似乎都与声明有关。我感兴趣的是如何构造相互依赖的对象,以及我的方法是否存在潜在的缺陷。考虑这个简单的例子: #include <iostream> #include <vector> using namespace std; class A; //Forward declaration class B{ public: B(string name, A* a):myA(a), name(name){

我通读了很多循环依赖性主题,但它们似乎都与声明有关。我感兴趣的是如何构造相互依赖的对象,以及我的方法是否存在潜在的缺陷。考虑这个简单的例子:

#include <iostream>
#include <vector>
using namespace std;

class A; //Forward declaration

class B{
    public:
        B(string name, A* a):myA(a), name(name){
            cout << "Works with pointer" << endl;
        };
    private:
        A* myA;
        string name;

};

class A{
    public:
        A(){
            cout << "Constructing A" << endl;
            if(bs.empty()) cout << "Vector is empty" << endl;
            bs.push_back(B("First", this));
            cout << "Array has " << bs.size() << " elements." << endl;
        };
    private:
        std::vector<B> bs;
};


int main() {
    cout << "Start" << endl;
    A a;
    cout << "Ok." << endl;
    return 0;
}
我能做些什么来避免B中的A*指针吗

理想情况下,我希望有一个引用,但如果我将B的构造函数更改为Bstring name,a&a,然后将push_更改回bs.bush_backfirst,*这;我收到一个错误:非静态引用成员“A&B::myA”无法使用默认赋值运算符


据我所知,编译器合成的运算符=不适合这里。正确的运算符=看起来如何?还是我一起走错了方向

在标准容器中使用类型(如vector)时,该类型需要可复制且可分配。如果您的类型具有指针成员,则这些成员可以与隐式定义的复制赋值运算符配合使用,但引用成员的情况并非如此,因为引用无法恢复


如果希望类型在容器中工作,那么使用指针成员要简单得多。您是否可以定义一个在特定情况下有意义的复制分配运算符并不明显,通常情况下是没有意义的。

当您在标准容器中使用类型时,例如vector,该类型需要是可复制和可分配的。如果您的类型具有指针成员,则这些成员可以与隐式定义的复制赋值运算符配合使用,但引用成员的情况并非如此,因为引用无法恢复


如果希望类型在容器中工作,那么使用指针成员要简单得多。您是否可以定义一个在特定情况下有意义的复制赋值运算符并不明显,通常情况下是没有意义的。

即使使用用户定义的赋值运算符,也不能在那里使用引用,因为引用一旦初始化就无法恢复。在此处使用指针是最简单的方法。

即使使用用户定义的赋值运算符,也不能在此处使用引用,因为引用一旦初始化就无法恢复。在这里使用指针是最简单的方法。

在这种情况下,只有在这种情况下,您可以考虑将B设为模板。

template <typename SomeA>
class B{
    public:
        B(string name, SomeA& a):myA(a), name(name){
            cout << "Works with reference" << endl;
        };
    private:
        boost::optional<SomeA&> myA;
        string name;
};

class A{
    public:
        A(){
            cout << "Constructing A" << endl;
            if(bs.empty()) cout << "Vector is empty" << endl;
            bs.push_back(B<A>("First", *this));
            cout << "Array has " << bs.size() << " elements." << endl;
        };
    private:
        std::vector<B<A> > bs;
};
这个建议完全没有任何上下文…

在这种情况下,只有在这种情况下,你可以考虑把B变成模板…

template <typename SomeA>
class B{
    public:
        B(string name, SomeA& a):myA(a), name(name){
            cout << "Works with reference" << endl;
        };
    private:
        boost::optional<SomeA&> myA;
        string name;
};

class A{
    public:
        A(){
            cout << "Constructing A" << endl;
            if(bs.empty()) cout << "Vector is empty" << endl;
            bs.push_back(B<A>("First", *this));
            cout << "Array has " << bs.size() << " elements." << endl;
        };
    private:
        std::vector<B<A> > bs;
};

这个建议完全没有任何上下文…

如果你有循环依赖,那么你应该删除它,而不是寻找更多的解决方法。嗯,我的语言不可知域模型有循环依赖。我有没有办法在类设计级别解决这个问题?如果你有循环依赖,那么你应该删除它,而不是寻找更多的解决方法。嗯,我的语言不可知域模型有循环依赖。我有没有办法在课堂设计层面上解决这个问题?这有什么帮助?B仍然包含一个引用,所以仍然是不可赋值的。@Mike,啊,废话,我只回答了一部分-我根本没有想到B被保持在向量中的事实。。。现在已修复..这有什么帮助?B仍然包含一个引用,所以仍然是不可赋值的。@Mike,啊,废话,我只回答了一部分-我根本没有想到B被保持在向量中的事实。。。现在修好了。。