2012-02-03 9 views
3

申し訳ありませんが、タイトルが不明ですが、私はすぐに言葉で苦労しています。私はちょうどそれに飛び込むます:この法的/安全なC++ですか? (同じサイズの継承クラスにダウンキャスト)

class A 
{ 
public: 

protected: 
    int doSomething(); 
}; 

class B : public A 
{ 
public: 
    int doSomething() { return A::doSomething(); } 
}; 

... 

A *a = new A; 
B *b = static_cast<B*>(a); 

cout << b->doSomething(); 

は特に、BはAを継承し、任意のデータメンバや仮想関数を追加しないと、任意の仮想関数をオーバーライドしません。つまり、BのインスタンスはAのインスタンスと同じになるはずです。

基本的には安全ですか?私はそれが合法ではないと確信していますが、移植可能ですか?このようなことに頼ることの潜在的な影響はありますか?

明らかにこれは悪い習慣ですが、私はそれを見ているように見えます。それは代替物よりもよいかもしれません。しかし、もしあなたがそれが悪いかもしれない非明白な理由がある、私は間違いなく興味がある。

答えて

1

明らかに悪いことは起こりませんが、なぜこのようなことを強制されるのでしょうか?

あなただけのラッパーをしたい場合は、作るBのメンバー、およびBは、このコードは悪くないですA.

+0

デザインによって異なります。 BがAと同じ型になることを望むかもしれません(Bのインスタンスを使用するのは、どこでも可能です)。また、後でBを拡張することもできます。 – vulkanino

+0

編集:実際には、私はあなたの答えを読んだので、私はあなたが意味するものを参照してください。これは間違いなく有効な点です。 –

2

へのコールを転送できるようにするには非常にクリーンなデザインですが、それはあなたを買うdosn't何でもあなたは同じことをすることができますが、このようなことをすることによって柔軟に構成を提供します。

class A 
{ 
public: 

protected: 
    int doSomething(); 
}; 

template <class T> 
class B : public T 
{ 
... 
} 

クライアントコードでは、機能セットを提供するオブジェクトを作成できます。ヴォルディックテンプレートを含むことで、コンシューマの観点からオブジェクトを構築することができます。

B<A> Ob; 

また、CRTPパターンを見てください。

+0

これは優れた点です。しかし、私は@kotlinskiに答えを出すことを選んでいます。答えは質問に近いからです。 –

1

私はそれが合法ではないと確信していますが、移植性がありますか?

携帯できる唯一の方法は合法です。 「ポータブル」とは、同様の小さなシステム間での移植を意味します。

+0

実際、私は同様のシステムの小さなセットを意味します。これはC++の既存の実装の大部分を記述しています。 もちろん、あなたは技術的なことをしようとしていますが、合理的にしようとしています。誰かがこれを壊してしまったからといって、彼らがやることを意味するわけではありません。 –

+0

@ジョン - 私はいつか*休止するだろうと確信しています。クラスBのオブジェクトを作成せずにクラスBから関数を呼び出すと、コンパイラオプティマイザはそれを把握して関数を削除することができます。 –

+0

@BoPerssonいいえできません。私はそれのポインタを持って、それに何かをキャストし、それを使用しています。その関数を最適化すると、リンカーエラーが発生します。とにかくリンク時に関数を最適化する必要があります。そのため、クラスがメンバ関数を最適化するためにnew'dされていないという事実を使用するのは絶対に意味がありません。代わりに関数の参照を見てください。 しかし、それは実際のトリックがまだ機能するので、とにかく議論のポイントです。あなたがしなければならないことは、あなたの(壊れた)コンパイラに、それを妨げる何かをして最適化しないよう伝えることです。 –

関連する問題