2

まず、質問は 、追加機能を備えた派生クラスへの共有ポインタのダウンキャストに非常に似ています。ここで、良い答えがあります。しかし、これが有効である(または無効である)理由と、共有ポインターを使用しない場合について説明したいと思います。それで :

class Base { /* ... */ };

class Derived : public Base
{
public:
    void additionnalFunc(int i){ /* access Base members */ }
};

int main(){
Base b;
Derived* d = (Derived*) &b; // or static_cast ?
d->additionnalFunc(3); // works ok.
}

これはgccで期待どおりに機能します。だから私の質問はそれが安全/有効ですか?コンパイラやアーキテクチャを使用しますか?そうでない場合、なぜですか?

この質問の理由を説明するために、ここにコンテキストがあります。

  • 「ベース」オブジェクトがあります。
  • Baseクラスを変更できません
  • いくつかの追加関数を除いて、Baseと同じインターフェイスを必要とする一連のテンプレート関数があります。
  • このテンプレート化されたライブラリをBaseオブジェクトで使用できるようにしたい
  • 追加機能のため、上記は不可能です。ただし、これらの関数はBaseから実装するのは簡単です。
  • また、できるだけ効率的にしたい(変換や間接化を避ける)

したがって、上記のトリックが有効である場合、それは良い解決策になる可能性があります...しかし、おそらくこの問題を解決するためのより良い設計がありますか?

4

1 に答える 1

2

これは未定義の動作です。特定のコンパイラで「動作する」かどうかは、おそらく重要ではありません。一般的にこれが機能することを信頼することはできません。*

あなたが説明したシナリオでは、最良の解決策はBase、引数としてをとるいくつかの無料の関数を作成することであるように思われます。もちろん、必要な機能がprotectedメンバーに依存している場合は、問題があります。(そして、そのようなアクセスを必要としないようにする方法を見つける以外に、良い解決策があるかどうかはわかりません。)


*コンパイラを変更したことがない場合でも、これは当てはまります。コンパイラーは、すべてのコードが「正しい」と自由に想定できるため、コードを少し変更すると、上記のトリックが役に立たなくなる最適化がトリガーされる可能性があります。

(もちろん、これが確実に発生することを示唆するつもりはありません。単に発生する可能性があるということです。)

于 2013-03-10T22:15:54.780 に答える