2017-05-12 5 views
0

マイ基底クラスはAccount呼ばれます。 次のような状況でスライスが発生するはずですか?これは明らかに私の場合に起こります。その後スライシングは

vector<shared_ptr<Account>> vec; 
shared_ptr<Businessaccount> sptr = make_shared<Businessaccount>(); 

vec.push_back(sptr); 

を、私はこれを行う場合:

(*vec.at(0)).getx(); 

それはclass<Account>getx()をという名前のメンバーを持っていないことを言います!

なぜこのようなことが起こり、どのように修正するのか、誰かに教えていただければ幸いです。

+1

これはスライスされていませんが、もちろん、コンパイラは 'at()'から返されたポインタを直接派生クラスのメンバー関数にアクセスすることはできません – MikeMB

+0

'Account'は' getx ) '? –

+0

ポインタを介してメソッドを呼び出す典型的な方法は ' - >'演算子です。 'vect.at(0) - > getx();' –

答えて

0

(*vec.at(0))は、を返します。これは約xを知らないでしょう。そのメンバーを参照するにはAccountポインタをBusinessaccountにキャストする必要があります。

shared_ptr<BusinessAccount> bA = dynamic_pointer_cast<BusinessAccount>(vec.at(0)); 
bA->getx(); 
+0

@FatihBAKIR ['dynamic_pointer_cast'](http://www.cplusplus.com/reference/memory/dynamic_pointer_cast) – lcs

0

いいえ、スライシングはこのような状況では発生しません、あなたのポインタがちょうどあなたのデータが変更され、ポインタのと同じ、ただのタイプがある。すなわち、基本クラスへのポインタに変換されます。スライスすると、派生クラスのすべてのデータが失われます。

いずれかの問題にあなたを解決する適切Businessaccountに実装される基底クラスの仮想メソッドを提供するか、または(あなたがオブジェクトが別の問題でBusinessaccountを入力していることを確信している場合)dynamic_castまたはstatic_castを使用する必要があります。このようなキャストを使用することは、通常、うまく設計されていないプログラムの兆候です。

0

C++では、指定されたオブジェクトの静的型と動的型が異なる場合があります。

あなたの静的タイプは、そのvecが指す共有ポインタはAccountです。

そのvecポイント内の共有ポインタがどのように変化するかの動的タイプ。あなたのケースでは、あなたはそれにBusinessaccountを入れます。

メソッドにアクセスまたは呼び出したい場合は、静的型メソッドのみにアクセスできます。

スタティック型は、その行に型が含まれていることをコンパイラに証明したものです。

がよく分かる場合は、static_cast<Businessaccount*>(vec.at(0).get())->getx()とすることができます。そうすることで、その場所のデータが実際にはBusinessaccountであることを特定していることをコンパイラに知らせることになります。あなたが間違っていると、あなたのプログラムの動作は未定義です(あなたがクラッシュして幸運な場合)。

RTTI(実行時のタイプ情報)をに指定することもできます。特定のオブジェクトが特定のサブタイプ(場合によっては仮想メソッドがある場合)の場合は、を入力します。

Account* paccount = vec.at(0).get(); 
Businessaccount* pba = dynamic_cast<Businessaccount*>(paccount); 
if (pba) 
    pba->getx(); 

上記チェックpaccountは実際Businessaccount*であり、そうである場合は、それにgetxを呼び出す場合。そうでなければ、何もしません。

ダイナミックキャスティングは、オブジェクトを正しく使用するように設計していないことが多い記号です。インプリメンテーションのインターフェイスにドリルダウンする必要があります。これは、インターフェイスが十分に豊かではないことを意味します。

一部のスクリプトとバイトコードのコンパイル言語では、あなたは外出してgetxを呼び出して、そのメソッドが存在しない場合はクラッシュ/例外/ etcをスローします。

代わりに(型システムを介して)あなたが主張しているものを使用することができます。次に、動的型チェックが必要な場合は、独自のハンドラを記述できます。

関連する問題