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
にもメンバー変数を持つことができる更新されたサンプルコードを参照してください。あなたは、単にBase
年代を使用することができます
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
5のルールではありません。 *ゼロのルール*。あなたのケースでは、 'Foobase'はRule of Zeroに従い、' Foo'の中のメンバーは特別な扱いを必要としないので、 'Foo'クラスの特別なメンバーの*は書きません。必要なことをすべてやりなさい。 – milleniumbug