1

Base->Center->Childの3つのクラスタイプがあり、親タイプから子タイプを構築できるようにしたいので、次のように宣言しました。

class Base {
public:
    Base(void) {cout << "Base()" << endl;}
    virtual ~Base(void) {}
    Base(const Base &ref) {cout << "Base(const Base &)" << endl;}
};
class Center : public virtual Base {
public:
    Center(void) : Base() {cout << "Center()" << endl;}
    Center(const Base &ref) : Base(ref) {cout << "Center(const Base &)" << endl;}
};
class Child : public virtual Center {
public:
    Child(void) : Center() {cout << "Child()" << endl;}
    Child(const Base &ref) : Center(ref) {cout << "Child(const Base &)" << endl;}
};

次のように呼び出しても問題ありません: (Center と Base のコピー コンストラクターを呼び出します)

Base base;
Center center(base);

.
ただし、これらのコードは予期しない動作をします。

Child child(base);

出力は次のとおりです。

Base()
Center(const Base &)
Child(const Base &)

Base(const Base &) の代わりに Base(void) と呼ばれるのはなぜですか?

解決済み (Dietmar Kühlと Adam Burry に感謝)
2 つの方法:

1. add Base(const Base &) to Child, which would looks like this:
   Child(const Base &ref) : Base(ref), Center(ref) {}
2. or, remove virtual inheritance, which would looks like this:
   class Center : public Base {...}
   class Child : public Center {...}
4

1 に答える 1

2

基本クラスへの引数virtualは、中間クラスではなく、最も派生したクラスによって提供されます。で受け取った引数を に渡したい場合Childは、次のようにコンストラクタBaseを実装する必要があります。Child

Child::Child(Base const& other)
    : Base(other)
    , Center(other)
{
}

ところで、関数が C++ で引数を取らないことを示す(void)代わりに使用するのは珍しいことです: C では、可変引数リスト関数と引数を取らない関数を区別するために、ある時点で必要でした (私は知りません)。これが C11 でも当てはまるかどうかを確認してください)。C++ では、括弧の空のペアは常に空の引数リストを示していました。()void

于 2013-09-14T02:48:31.763 に答える