2016-11-10 7 views
1

私はBaseクラスとそれから派生する2つのクラスOneとTwoを持っているとします。オブジェクト型は、実行時に決定されC++での派生型のインスタンス化

Base b; 
if(condition) 
    b = new One(); 
else 
    b = new Two(); 

(上記のオブジェクトはヒープ上に行く):Javaでは、私は次のシナリオを持つことができます。

実行時にオブジェクト型をインスタンス化できるようにしたい - 私が知っているのは、両方が同じBase型を共有していることです - しかし、スタックを割り当てたままにしておきます。

Base b; 

これを行うにはどうすればよいですか?

+1

でメモリを削除する必要があります - どれも(Javaは、スタック上のオブジェクトを割り当てませんので、これらの2例がありませんありません同じ)。もしあなたができたとしても、あなたのオブジェクトは 'Base'型にのみスライスされます(http://stackoverflow.com/questions/274626/what-is-object-slicing)。 –

+1

あなたは(アドバイスされた方法で)維持することはできません。割り当てられたスタックなので、割り当て時にそのサイズを知る必要があります。 Javaでは、オブジェクトがスタックに割り当てられていないことを覚えています.C++で書かれたJavaコードはスタックの割り当てを意味しますが、それはJavaでは意味しません。 – djgandy

+0

これは古典的なXYの問題です - http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Slava

答えて

1

これを行うにはどのような方法が最適ですか?

できません。変数型をBaseと宣言した場合、そのスタック割り当てはBaseのインスタンスを保持するのに適していますが、派生型のインスタンスはありません(より大きいかもしれませんが、そうでない場合でも、 C++の変数の実行時の型は常に宣言された型と同じです)。最高でもsliceの派生インスタンスをBase型変数に含めることができます。

shared_ptrまたはunique_ptrに任意にラップされたポインタを使用することをおすすめします。所有権が移譲されていないと仮定して、スコープから外れたときにオブジェクトが自動的に破棄されるようにする)。

Base* b = (condition) ? (Base *) new One() : new Two(); 
auto bptr = shared_ptr<Base>(b); 

これはJavaと事実上同じです。オブジェクト自体はヒープに割り当てられていますが、その参照はスタックに割り当てられています。この構文にもかかわらず、参照型Java変数は基本的にC++のポインタと同等です。

-1

C++で継承を使用するには、静的オブジェクトではなくポインタを定義し、newキーワードでインスタンス化する必要があります。

例:

Base* b; 
if(condition) 
    b = new One(); 
else 
    b = new Two(); 
0

は、例えば、テイク:

Derived d; 
Base* b = &d; 

dは、スタック(自動メモリー)であるが、多型は、まだb上で動作します。

基本クラスのポインタまたは派生クラスへの参照がない場合、派生クラスを持たないため、多態性は機能しません。 をスライスするためcオブジェクトは、BaseDerivedではありませんが、

Base c = Derived(); 

してください。だから、技術的には、多形性はまだ機能しています。ちょうどあなたが話すオブジェクトDerivedがなくなっただけです。

は今

Base* c = new Derived(); 

cを取るだけでメモリ内のいくつかの場所を指して、あなたは本当にそれが実際にBaseDerivedのかどうか気にしませんが、virtualメソッドの呼び出しが動的に解決されます。

Javaと違って、ヒープ割り当てやポインタウェイなしで動的バインディングを実現する方法はありません。

0

コメントは言っていません。さて、あなたはそれが実行されませんでした:

Base &b = *(condition ? (Base *)&One() : (Base *)&Two()); // BROKEN CODE DO NOT USE 

を(!-fpermissiveを使用して作成しますが、これをしない)

Two & One以来、オブジェクトは一時オブジェクトです。 bは次の行を踏むと無効になります=>これをしないでください(私はすでにそれを言っていませんでした)

以下は動作しますが、完全ではありません。あなたはそれを買う余裕があります。ただ、状況に合わせてお選び:

One one; 
Two two; 
Base &b = *(condition ? (Base *)&one : (Base *)&two); 

ダブル割り当てを避けるために、私は使用量の面で考えることができます最も近いものは、割り当てられたオブジェクト(まだない自動変数、申し訳ありません)の基準を取るために次のようになります。

Base &b = *(condition ? (Base *)new One() : (Base *)new Two()); 

bをコードにBaseとして使用することができます。

あなたのオブジェクトがスタックに割り当てられるようにしたい場合はあなたがまだ

delete (&b); 
+0

申し訳ありませんが、私がテストしていない唯一のコード:)は修正されました。 –

関連する問題