我阅读了很多循环依赖主题,但所有这些主题似乎都与声明有关。我感兴趣的是如何构建相互依赖的对象,以及我的方法是否存在潜在的缺陷。考虑这个简单的例子:
#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;
}
我可以做些什么来避免A*
中的B
指针?
理想情况下,我希望有一个引用,但如果我将B
的构造函数更改为B(string name, A& a)
,然后将push_back更改为bs.bush_back(B("First", *this));
,则会收到错误:{{1} }。 See the modified example
据我所知,编译器合成的non-static reference member 'A& B::myA', can't use default assignment operator
不适合这里。正确的operator=
看起来怎么样?或者我一起走错了方向?
答案 0 :(得分:5)
在标准容器中使用类型时,如vector
,类型需要 CopyConstructible 和可分配。如果你的类型有指针成员,那么这些将适用于隐式定义的复制赋值运算符,但引用成员不是这种情况,因为引用不能反弹。
如果您希望您的类型在容器中工作,那么坚持使用指针成员会更加简单。是否可以定义一个在特定情况下有意义的复制赋值运算符并不明显,通常它不是。
答案 1 :(得分:0)
即使使用用户定义的赋值运算符,也无法使用引用,因为引用初始化后无法反弹。在这里使用指针是最简单的方法。
答案 2 :(得分:0)
在这种情况下(在这种情况下仅 ),您可以考虑将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;
};
这个建议完全没有任何背景......