-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

每只家猫都是猫,但每只猫都不是家猫。因此,如果您打算学习多态性(从您的代码中看起来是这样),请记住允许转换为基类指针/引用,从基类指针/引用转换为子类并不容易。您必须明确使用 dynamic_cast。

但是,除此之外,您的代码还有许多其他问题。方法咆哮应该被声明为虚拟,你应该为它指定一个返回类型,你不能从外部调用私有成员函数((cats [0])->咆哮()不会编译)。

于 2012-06-11T12:12:38.217 回答