Pointer of base class type forgets original object type
我有一个指向从同一个基类派生的对象的指针向量。问题是,在调用函数(而不是方法)时,会忘记原始对象的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 } |
有解决办法吗?
向
Cat 添加另一个虚拟函数as(也添加虚拟析构函数):1
2
3
4
5
6class Cat{
//base class
~virtual Cat() {} //add a virtual destructor as well
virtual void growl() = 0;
virtual void call_function() = 0;
};并按以下方式实施:
1
2
3
4
5class HouseCat : public Cat{
//derived class
virtual void growl(){};
virtual void call_function() { function(*this); }
};然后你可以写下:
1cats[0]->call_function();最终将调用适当的
function() 过载。或者简单地将
function 实现为类层次结构中的虚拟成员函数。
你可以有一个
或者可以让
家猫都是猫,但不是家猫。因此,如果您打算学习多态性(从代码中,看起来是这样的),请记住,允许强制转换为基类指针/引用,从基类指针/引用强制转换为子类并不容易。您必须显式地使用动态u cast。
但是,您的代码还有许多其他问题。方法growl应声明为virtual,应为其指定返回类型,不能从外部调用私有成员函数((cats[0])->growl()将不编译)。