我有一个指向对象的指针向量,这些对象派生自同一个基类。问题是在调用函数时(但不是方法)忘记了原始对象的类型。
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
}
有解决方法吗?
答案 0 :(得分:4)
将另一个虚拟函数添加到Cat
为(add virtual destructor as well):
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
实现为虚拟成员函数。
答案 1 :(得分:3)
您可以拥有dynamic_cast
(我假设您遗漏了virtual
且growl
是虚拟的)。
或者您可以将function
作为参数Cat&
,IMO是最干净的方式。
答案 2 :(得分:1)
每只HouseCat都是Cat,但每只Cat都不是HouseCat。因此,如果您打算学习多态(从您的代码中看起来如此),请记住,允许转换为基类指针/引用,从基类指针/引用到子类的转换并不容易。您必须明确使用dynamic_cast。
但是,除此之外,您的代码还有许多其他问题。方法growl应该声明为virtual,你应该为它指定一个返回类型,你不能从外面调用私有成员函数((cats [0]) - &gt; growl()不会编译)。