-1

同じ基本クラスから派生したオブジェクトへのポインターのベクトルがあります。問題は、関数 (メソッドではなく) を呼び出すときに、元のオブジェクトの型が忘れられることです。

class Cat{
    //base class
public:
    virtual void growl() = 0;
};

class HouseCat : public Cat{
    //derived class
public:
    void growl(){};
};

class AlleyCat : public Cat{
    //derived class
public:
    void growl(){};
};

void function(HouseCat& a){};
void function(AlleyCat& a){};

int main(){
    vector<Cat*> cats;
    cats.push_back(new HouseCat);
    cats.push_back(new AlleyCat);
    function(*(cats[0])); //error: cannot convert parameter 1 from 'Cat' to 'HouseCat &'
    (cats[0])->growl(); //this works though

}

回避策はありますか?

4

3 に答える 3

4
  • 別の仮想関数をCatasに追加します (仮想デストラクタも追加します):

    class Cat{
       //base class
        ~virtual Cat() {}  //add a virtual destructor as well
         virtual void growl() = 0;
         virtual void call_function() = 0;    
    };
    

    そしてそれを次のように実装します:

    class HouseCat : public Cat{
       //derived class
       virtual void growl(){};
       virtual void call_function() {  function(*this); }
    };
    

    次に、これを書くことができます:

    cats[0]->call_function();
    

    function()最終的に適切なオーバーロードを呼び出します。

  • またはfunction、クラス階層で仮想メンバー関数として実装するだけです。

于 2012-06-11T12:07:01.943 に答える
3

あなたは持つことができますdynamic_cast(私はあなたが取り残したvirtualと仮定しています、そしてそれgrowlは仮想です)。

またはfunction、パラメーターとして a を使用することもできますCat&。これは、IMO では最もクリーンな方法です。

于 2012-06-11T12:04:53.577 に答える
1

すべてのHouseCatは猫ですが、すべての猫はHouseCatではありません。したがって、ポリモーフィズムを学習する場合(コードから、そのように見えます)、基本クラスのポインター/参照へのキャストは許可されていますが、基本クラスのポインター/参照からサブクラスへのキャストは簡単ではないことに注意してください。dynamic_castを明示的に使用する必要があります。

ただし、コードにはこれ以外にも多くの問題があります。メソッドgrollは仮想として宣言する必要があり、その戻り型を指定する必要があります。外部からプライベートメンバー関数を呼び出すことはできません((cats [0])-> growl()はコンパイルされません)。

于 2012-06-11T12:12:38.217 に答える