4

私は古典的な仮想継承ダイヤモンドを持っています:

class A {
protected:
    A(const char *x) { ... }
}

class B: public virtual A {
protected:
    B(): A(NULL) { ... }
public:
    virtual void foo() = 0;
}

class C: public virtual A {
protected:
    C(): A(NULL) { ... }
public:
    virtual void bar() = 0;
}

class D: public B, public C {
public:
    D(const char *x): A(x) { ... }
    void foo();
    void bar();
}

Bandで NULL を使用しますC。これらは抽象クラスであるためA、コンストラクターで ctor が呼び出されることはありません。NULLコンストラクターで指定するか、パラメーターなしのコンストラクターを宣言する以外に、それを行うためのより良い方法はありますAか? コンストラクターをパラメーターで呼び出す必要があるため、A() {}ctor は抽象クラスでのみ許可する必要があります。

4

4 に答える 4

0

厳密な答えはおそらく存在しないので、私はこれを閉じます。IMOの最善の回避策は

struct AbstractPlaceholder {
    AbstractPlaceholder() {
        assert(false);
    }
};

class A {
protected:
    A(const AbstractPlaceholder &ap) {}
    A(const char *x) { ... }
};
于 2012-01-13T23:21:44.877 に答える
0

あなたのアプローチのバリエーションは

class A {
protected:
    A(const char *x = NULL) {
      assert(x && "A mustn't be default constructed!");
    }
};

これにより、より意味のある診断が追加されます。


ただし、 ( を介した正当な構造として) であることを明示的に許可xしたい場合は、型を使用できます。NULLCMaybe

template <typename T> class Maybe {
  T const t; // must be default constructible!
  bool const invalid;
  public:
    Maybe() : t(), invalid(true) {}
    Maybe(T t) : t(t), invalid(false) {}
    bool nothing() const {
      return invalid;
    }
    T just() const {
      assert(!invalid);
      return t;
    }
};

次に、コンストラクターを次のように変更できます

A::A(Maybe<const char*> mx) {
  // either
  assert(!mx.nothing());
  // or
  mx.just();
}
于 2012-01-13T23:44:31.303 に答える
0

次のように変更できますA

class A {
private:
    A() {};
    friend class B;
    friend class C;
protected:
    A(const char *x) { }
};

そして、B(): A() {}動作しますC(): A() {}が、動作しませD(const char*): A() {}ん。しかし、これは本当に厄介です。私はNULLあなたが今使っているものに固執します。

しかし、これは確かに興味深いケースです。inのコンストラクターを指定しなけれならない技術的な理由は考えられません。それらが作成されることはなく、継承者はとにかく初期化されます。ABCA

于 2011-10-09T13:01:00.337 に答える
0

でデフォルト引数を指定できますA(const char*)

class A {
protected:
    A(const char *x = 0) { ... }
                    ^^^^
};

ただし、これによりD回避も可能になりA()ます。

于 2011-10-09T13:02:08.580 に答える