2012-02-04 25 views
0

私はクラスに少し問題があります。コードでC++クラスの継承

class A 
{ 
public: 
    int num; 
    sayNum() { cout<<num;} 
}; 

class B : public A 
{ 
public: 
    sayNum() { cout<<"my num is: "<<num;} 
}; 

/*somewhere else...*/ 
A foo[10]; 

B something; 
something.num=10; 

foo[0]=something; 

foo[0].sayNum(); 
/*...*/ 

Iがfoo [0] .sayNumを呼び出すとき();それは "10"を印刷し、 "私の数は10です"と印刷します。私は配列の型を変更することはできません。 D)

答えて

4

この行:

foo[0]=something; 

を配列にコピーします。 something(すなわち、クラスB)のタイプはfoo[0](すなわちクラスA)のタイプと同じではないので、変換がある。この場合、somethingスライスになり、A部分だけが生き残ります。

最終結果はfoo[0]はまだタイプclass Aを持つオブジェクトが含まれているため、決してが出力されます「私のnumがある」ということです。

sayNum()をバーチャルに変更すると、コードに表示されるその他の問題を解決するのに役立ちますが、この場合は役に立ちません。

どのように解決するかは、達成したいことによって異なります。考えられる解決策は以下のとおりです。

  • 変更ポインタを格納するための配列:A* foo[10];注:これは、あなたが「新しい」と「削除」を使用する必要がありますを意味します。
  • 配列の代わりにstd :: vectorを使用してください。std::vector<A*> foo;追加の利点:ベクターは必要に応じて拡大縮小できます。
  • スマートポインタstd::vector<std::shared_ptr<A> > foo;その他の利点:deleteについての心配はもうありません。

しかし、達成したいことを知らずに、正しいアプローチを提案することは不可能です。

1

の定義における仮想する機能sayNumを宣言します:

virtual void sayNum() { cout<<num;} 

編集:おかげで、それは私がそれを理解することは難しいだろう、ここで地雷を貼り付ける場合は、単に例のコードであることに注意してくださいSjoerdのコメントに - これはまだあなたを助けません。あなたがポリモーフィズムを利用したい場合、あなたはA.

に変換foo[0]somethingを割り当てることによって、むしろその後、クラスA

+5

Althougそれは良いアドバイスです、この場合は十分ではありません。配列への代入はオブジェクトをスライスし、A部分のみが配列にコピーされます。 – Sjoerd

+0

@Sjoerdどのようにして、さまざまなクラスの配列を格納できますか? –

+0

@kittyPL格納するタイプの共通基本クラスにポインタ(またはスマートポインタ)を格納することによって。 – Sjoerd

1

ないの配列をクラスへのポインタの配列を作成する必要がありますこれは、intfloatを割り当てるのと似ています。すべての小数を失います。

1
  1. 各クラスの関数の戻り値の型がありません。あなたは戻り値の型がvoidになりたいと言う:

    void sayNum() { cout<<num;}

  2. 配列の要素にアクセスする場合、配列オブジェクトに添字を使用します。たとえば

    foo[0]=something;

+0

これは彼が持っている問題ではありません。 –

+1

@izomorphius:OPのコードは**コンパイルさえしません**。 – cpx

+0

私は同意します。あなたが指摘した問題が修正されたとしても、彼の問題は引き続き存在することを示すためにコメントを追加しました。 –

4

1.あなたはA*の代わりAを使用する必要があります
をスライスすることは避けてください。あなたのようにあなたのコードを

class A 
{ 
public: 
    int num; 
    virtual void sayNum() { cout << num; } 
}; 

What is object slicing?

2.あなたがクラスAA
virtualとして定義は次のようになります。クラスのsayNum()関数を宣言する必要があります。これは、理由を理解助けることができますたとえば、somewhere elseは次のようになります。

A* foo[10]; 

B something; 
something.num=10; 

foo[0] = &something; 

foo[0]->sayNum();