在C++中探索基於策略的設計模式時,我偶然發現了一個我找不到解決方案的問題:如何編寫基於策略的類的複製和移動構造函數方式而不涉及策略類內的成員變量?基於策略的設計中的C++複製/移動構造函數
下面是一個例子:
class Foobase {
public:
Foobase(int v) :val(v) { }
protected:
int val;
};
template <typename Base>
class Foo : public Base {
public:
Foo(int v):Base(v) { }
// how can I initialize Base() class without referring to it's protected members?
Foo(const Foo<Base>& other) :Base(other.val) { }
};
int main() {
Foo<Foobase> foo(5);
auto foo2 = foo;
}
在上面的代碼中,複製的class Foo
構造使用受保護成員變量初始化Base
類。除上述以外是否還有其他方式可以初始化Base
?這種情況下的最佳做法是什麼?
更新問題:
通過@LogicStuff答案澄清問題的拷貝構造函數部分,但是沒有接聽移動的構造問題。請參閱更新的示例代碼,其中class Foo
也可以具有成員變量。
class Foobase {
public:
Foobase(int v) :val(v) { }
Foobase(const Foobase&) = default;
Foobase(Foobase&&) noexcept = default;
Foobase& operator= (const Foobase&) = default;
Foobase& operator= (Foobase&&) noexcept = default;
void Print() const {
std::cout << val << std::endl;
}
protected:
int val;
};
template <typename Base>
class Foo : public Base {
public:
// works fine
Foo(std::string str, int v):Base(v), name(str) { }
// works fine
Foo(const Foo<Base>& other) :Base(other), name(other.name) { }
// I'm doubtful about this c'tor, if I move `other` for initializing Base,
// how can I initialize `name` variable?
Foo(Foo<Base>&& other)
:Base(std::move(other)), name(std::move(other.name) /* will this be valid?? */) { }
// can we have copy and assignment operator for this class?
void Print() {
std::cout << "name = " << name << std::endl;
Base::Print();
}
private:
std::string name;
};
int main() {
Foo<Foobase> foo("foo", 5);
auto foo2 = std::move(foo);
foo2.Print();
}
爲什麼你首先定義拷貝構造函數?使用零規則。 – milleniumbug
這裏複製構造函數是一個例子,我將在實際用例場景中遵循5的規則! – Pranav
不是五的規則。 *零規則*。在你的情況下,'Foobase'遵循Rule of Zero,'Foo'裏面的成員都不需要特殊的處理,所以你*不會爲'Foo'類編寫任何*特殊成員,因爲默認的成員將會做所有需要的。 – milleniumbug