0

2 つのクラスがあり、そのうちの 1 つはもう 1 つのクラスを継承します。

class baseClass
{
public:
    virtual void show();
};

void baseClass::show(){cout << "Base class" << endl;}


class derivedClass
{
public:
    void show();
};

void derivedClass::show(){cout << "Derived class" << endl;}

派生クラス オブジェクトを作成して show 関数を呼び出すと、「派生クラス」が正しく出力されます。私が次のことをした場合:

derivedClass b;
baseClass* b;
b=&d;
b->show();

「派生クラス」が再び正しく出力されます。ただし、次のようにリストを作成すると:

list<baseClass> t;
list<baseClass>::iterator it;
baseClass b;
derivedClass d;
t.push_back(b);
t.push_back(d);

そして、各アイテムで show を呼び出してみてください:

it = t.begin();
it->show();
it++;
it->show();

b と d の両方の出力は「基本クラス」です。私の質問は、なぜ show() の baseClass バージョンのみを使用しているのですか? また、リスト内の派生クラスのオブジェクトに対して派生バージョンを適切に使用するにはどうすればよいですか?

前もって感謝します

4

2 に答える 2

1

ポリモーフィズムを機能させるには、メソッドshow()を宣言する必要があります。virtual

class baseClass
{
public:
    virtual void show();
};

void baseClass::show(){cout << "Base class" << endl;}


class derivedClass : public baseClass
{
public:
    virtual void show();
};

void derivedClass::show(){cout << "Derived class" << endl;}

あなたも行方不明でしたclass derivedClass : public baseClass

そして最後の問題。ポインタを使用する必要があります。

list<baseClass*> t;
list<baseClass*>::iterator it;
baseClass b;
derivedClass d;
t.push_back(&b);
t.push_back(&d);

これに変更します:

it = t.begin();
(*it)->show();
it++;
(*it)->show();
于 2011-09-18T03:15:08.380 に答える
0

「派生クラス」が再び正しく出力されます。ただし、次のようにリストを作成すると:

いいえ、「派生クラス」は出力できません。実際、この行:

b=&d;

はのポリモーフィック ベースではないため、コンパイル エラーが発生します。bd

基本クラスで、showとして宣言します。virtual

virtual void show();

次に、それがコンパイルされます。

ただし、show仮想を作成した後でも、派生クラスのオブジェクトをリストにプッシュすると、リストには基本クラスのオブジェクトしか含めることができないため、オブジェクトのスライスが発生します。つまり、リストは派生クラス オブジェクトのサブオブジェクトを取得します。リストを次のように宣言したためです。

list<baseClass> t;

これは正しくありません。

次のように宣言します。

list<baseClass*> t;

次のように、プッシュpointerしてこれに異議を唱えます。

derivedClass d;
derivedClass *pd = new derivedClass;
baseClass b;

t.push_back(&d);
t.push_back(pd); //note there is no `&`
t.push_back(&b);

//use t

//must delete pd
delete pd;

--

派生クラスのオブジェクトを削除する場合は、基本クラス型のポインターを使用して、次のように注意してください。

baseClass *bptr = new derivedClass();
delete bptr;

次に、のデストラクタをbaseClass仮想として定義する必要があります。そうしないと、上記の削除ステートメントによって未定義の動作が呼び出されます。

だからこれをしてください:

class  baseClass:
{
  //...
  virtual ~baseClass();
};
于 2011-09-18T03:18:37.170 に答える