ここにいくつかのコードがあります:
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にはいくつかのメンバー関数が追加されているだけで、オブジェクトの内部データは変更されていません。