2

ここにいくつかのコードがあります:

class containerA
{};

class containerB
: public containerA
{
    public: 
        containerB () {};

        containerB(const containerB& cb)
        {
            cout << "containerB copy ctor" << endl;
        }
};

class containerC
: public containerA
{
    public:
        containerC () {};

        containerC(const containerC& cc)
        {
            cout << "containerC copy ctor" << endl;
        }
};

class myType 
{
    public:

        void someFunction(const containerB& cB) 
        {
            cout << "someFunction(containerB)" << endl;
        }
};

上記の定義を変更できないと仮定した場合、「constcontainerC&」型の引数を使用してmyTypeの「someFunction」メソッドを呼び出すことができるメカニズムは何でしょうか。

私が見つけたのは、myTypeから新しい型を公に派生させ、reinterpret_castを使用して「someFunction」を次のように再定義することだけでした。

class myTypeNew
: public myType
{
    public:
        void someFunction(const containerC& cC)
        {
            cout << "someFunction(containerC)" << endl;

            const containerB& cbRef = reinterpret_cast<const containerB&>(cC);

            myType::someFunction(cbRef);
        }
};

これは安全ですか?私の推測では、someFunctionでの使用方法に関しては、containerBとcontainerCの演算子に依存します。

すべてのコンテナはテンプレート化されていますが、これは違いはありません。継承階層の問題です。

非常に重要:containerAを引数としてcontainerBとcontainerCに対して明示的な型変換が定義されているため、containerCを直接引数としてmyType :: someFunctionに渡すことができますが、この場合、コピーの構築が行われます。まさに私が避けたいもの。

いくつかの特定のメモ:

  • containerBとcontainerCの両方の属性はまったく同じです
  • someFunctionは、コンテナ要素にアクセスするためにopearator []のみを使用し、
  • operator + =(ただし、これはテンプレート要素レベルで定義されます)

containerBとcontainerCは、2つの一般的な異なるタイプではありません。containerCにはいくつかのメンバー関数が追加されているだけで、オブジェクトの内部データは変更されていません。

4

3 に答える 3

2

それはまったく安全ではありません。

someFunctionおそらくの一部であるメソッドを呼び出しますContainerB(そうでない場合はContainerA、パラメータータイプとして持つことができます)。

ContainerBそのメソッドが(であるため、タイプキャストしただけの)オブジェクトではないオブジェクトで呼び出されるとContainerC、悪いことが起こる可能性があります(たとえば、存在しないメンバー変数にアクセスしようとする)。

于 2011-11-25T13:19:16.000 に答える
2

いいえ、それは安全ではなく、未定義の動作の領域内にあると思います。

クラスcontainerBとcontainerCは、完全に2つの異なるタイプです(両方ともcontainerAから継承することを除いて)。

したがって、containerBとcontainerCに対してsomeFunction()を呼び出す唯一の「合法的な」方法は次のようになります。

  • タイプをカバーするsomeFunctionのオーバーロードを提供します
  • 基本クラスcontainerA内に十分なインターフェイスとともにsomeFunction(containerA&ca)を提供します
于 2011-11-25T13:20:25.763 に答える
1

一般的に安全ではありません

  • containerB containerA
  • containerC containerA

公的継承の定義によるが

  • containerB ではありませんcontainerC

したがって、あるタイプから別のタイプにキャストすることはできません。

FromCtoB(...)たぶん、必要な要素を与えられcontainerCたものから新しいものにコピーする関数を書くことを検討してcontainerBください。
これは、関連するデータが宣言されていない場合にのみ可能であることに注意してくださいprivate

于 2011-11-25T13:21:47.833 に答える