2016-03-20 12 views
2

私は変更できない既存のクラスAに非仮想メソッドを追加したいと思います。したがって、Aから継承したクラスBを作成し、必要なメソッドを追加します。さて、私がタイプAのオブジェクトを持っている場合、それをタイプBのオブジェクトと見なすことはできますか?言ってやるが、しかし、私は期待どおりに動作するために標準で保証されます場合は思っていた、法的次のコード?:C++では、非仮想メソッドのみを追加する派生クラスにキャストできますか?

class A { <...> }; 

class B: public A { 
    void f(); 
    }; 

A a(); 
void g(const B&); 
void h() { g(static_cast<B&&>(a())); } 

これは、コンパイルして仕事んです。私はなぜそうは見えないのですが、それでもきれいに感じません。

+0

いいえ、キャストによって未定義の動作が発生します –

+0

'B a;'の後に 'A&'を 'void foo(A & a);')のように引数として受け取り、あなたが実際に 'a'が本当に' b'であることを知っていれば、fooの内部で(あなたはどうでしょうか?)、キャストを実行することができるように 'foo(a)'を定義します。 –

+0

なぜオブジェクトをキャストしますか? – MikeMB

答えて

5

これは未定義の動作です。 Bクラスタイプであるタイプ「CV1のB」の左辺値

、BからDは、派生クラス あり、(項10)「CV2のDへの参照を」型にキャストすることができる。[expr.static.cast]からcv2は、cv1と同じcv-qualification、またはより大きいcv-qualificationであり、Bは仮想基本クラスではありません(4.10)。 、Dの仮想基本クラスの基本クラスでもありません。結果の型は "cv2 D"です。タイプ "cv1 B" のxvalueは、タイプ "cv1 B"の左辺値と同じ制約で、 "rvalue reference to cv2 D"とタイプすることができます。 タイプ "cv1 B"のオブジェクトが実際にタイプDのオブジェクトのサブオブジェクトである場合、その結果は、タイプDの同封の オブジェクトを参照します。そうでない場合、動作は未定義です。

a実際にタイプBのオブジェクトのsubojectではない - それはちょうどタイプAのは本当にですので、動作は未定義です。

void f(A&); 

答えはあなたがAprivateまたはprotectedメンバーにアクセスする必要があるということであれば、へのそれらのメンバーがアクセスできないようにする意図があった:単に非メンバ関数を追加することからあなたを停止するために何

君は!

+0

何も私を止めることはありません。グローバル関数を使用することによって、OOPの利点の1つを失うことになります。C++があまりにも悪いことは、この問題の解決策を提供しません。 –

+1

@ YaronCohen-Tal OOPの欠点の1つを発見したように私にはさらに響きました。 – Barry

+0

Hehe、ええ、おそらく...それは、私はCに切り替えている! j.k ... –

関連する問題