5

既存の機能をそのままにして、一部のコードをリファクタリングしようとしています。オブジェクトへのポインタをベースインターフェイスにキャストし、後で派生クラスを取得するのに問題があります。プログラムは、ファクトリオブジェクトを使用して、特定の場合にこれらのオブジェクトのインスタンスを作成します。

これが私が扱っているクラスのいくつかの例です。

// This is the one I'm working with now that is causing all the trouble.
// Some, but not all methods in NewAbstract and OldAbstract overlap, so I
// used virtual inheritance.
class MyObject : virtual public NewAbstract, virtual public OldAbstract { ... }

// This is what it looked like before
class MyObject : public OldAbstract { ... }

// This is an example of most other classes that use the base interface
class NormalObject : public ISerializable

// The two abstract classes. They inherit from the same object.
class NewAbstract : public ISerializable { ... }
class OldAbstract : public ISerializable { ... }

// A factory object used to create instances of ISerializable objects.
template<class T> class Factory
{
public:
    ...
    virtual ISerializable* createObject() const
    {
        return static_cast<ISerializable*>(new T()); // current factory code
    }
    ...
}

この質問には、さまざまなタイプのキャスティングが何をするかについての良い情報がありますが、それは私がこの状況を理解するのに役立ちません。static_castと通常のキャストを使用するとerror C2594: 'static_cast': ambiguous conversions from 'MyObject *' to 'ISerializable *'。dynamic_castを使用すると、createObject()はNULLを返します。NormalObjectスタイルクラスと古いバージョンのMyObjectは、ファクトリの既存のstatic_castで機能します。

このキャストを機能させる方法はありますか?可能だと思います。

4

4 に答える 4

10

ISerializableから仮想的に継承する必要があります (VS2010 でテストしたところです)。これはDiamond Problemと呼ばれる一般的な問題で、コンパイラはどの階層パスを取るべきかを認識していません。

編集:

これはそれを行う必要があります:

class NewAbstract : public virtual ISerializable { ... } 
class OldAbstract : public virtual ISerializable { ... } 
于 2010-05-25T16:41:04.703 に答える
1

最初にすぐ近くの基地の1つにキャストすることで、それを回避できます。

virtual ISerializable* createObject() const
{
    NewAbstract*const na = dynamic_cast< NewAbstract* >( new T() );
    return dynamic_cast< ISerializable* >( na );
}
于 2010-05-25T16:41:29.063 に答える
0

NewAbstract と OldAbstract の両方から実質的に継承しないでください。仮想的に継承するものを 1 つ選択します。それで対処できると思います。

于 2010-05-25T16:34:19.743 に答える
-2

「恐ろしいダイヤモンド」と仮想継承を調べてください。彼らはあなたを助けるかもしれません。

于 2010-05-25T16:31:47.613 に答える