我有這樣的事情:當前向聲明不可能儘可能優雅時,如何解決循環類依賴性?
struct v_with_holder {
// bunch of fields
holder h; // does not name a type
};
typedef boost::variant</* such types, */v_with_holder/*, many others */> struct_v;
class holder { public: std::vector<struct_v> ss; };
我最近才加入這個特殊的變種。所有其他的只有標準的,已經定義的數據類型和類,所以它們可以是複製構建的,代碼庫就是這樣編寫的(例如調用ss.push_back(v)
)。
問題是,我不能申報v_with_holder
,直到我宣佈holder
,反之亦然。前向聲明class holder;
給出field 'h' has incomplete type 'holder'
。
我想我可以用一個unique_ptr
:
class holder;
struct v_with_holder {
// bunch of fields
std::unique_ptr<holder> ph;
holder& h;
v_with_holder();
~v_with_holder();
};
typedef boost::variant</* such types, */v_with_holder/*, many others */> struct_v;
class holder { public: std::vector<struct_v> ss; };
v_with_holder::v_with_holder() : ph(new holder), h(*ph) { }
v_with_holder::~v_with_holder() { }
然而,現在的問題是,v_with_holder
不再拷貝構造:
holder h1, h2;
v_with_holder x;
x.h = h2;
h1.ss.push_back(x); // error: use of deleted function 'v_with_holder::v_with_holder(const v_with_holder&)'
現在看來,我的唯一的辦法是定義複製構造函數,它們只是創建新的獨特ptrs並複製內容。爲了完整性,還要移動構造函數。這似乎工作(ideone link),但它意味着我已經從我的意圖,這是該得到:
struct v_with_holder {
// bunch of fields
holder h;
}
// define struct_v, holder
對此horribleness:
class holder;
struct v_with_holder {
// a bunch of fields
std::unique_ptr<holder> ph;
holder& h;
friend void swap(v_with_holder& first, v_with_holder& second)
{
using std::swap;
// swap a bunch of fields
swap(first.ph, second.ph);
}
v_with_holder();
~v_with_holder();
v_with_holder(const v_with_holder& other);
v_with_holder(v_with_holder&& other);
v_with_holder& operator=(v_with_holder other);
};
// define struct_v, holder
v_with_holder::v_with_holder() : ph(new holder), h(*ph) { }
v_with_holder::~v_with_holder() { }
v_with_holder::v_with_holder(const v_with_holder& other) : ph(new holder), h(*ph)
{
// copy a bunch of fields
h = other.h;
}
v_with_holder::v_with_holder(v_with_holder&& other) : v_with_holder()
{
swap(*this, other);
}
v_with_holder& v_with_holder::operator=(v_with_holder other)
{
swap(*this, other);
return *this;
}
和所有以避免循環依賴!
當然,一定有更好的辦法。告訴我有更好的方法。請。什麼是更好的方法?
爲什麼downvote?讓我知道這是不是題外話,或者我可以如何改進這個問題。 – Claudiu