基类类型的指针忘记了原始对象类型
Pointer of base class type forgets original object type
我有一个指向派生自同一基类的对象的指针向量。问题是在调用函数(而不是方法)时忘记了原始对象的类型。
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
为(也添加虚拟析构函数):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
实现为虚拟成员函数。
你可以有一个dynamic_cast
(我假设你遗漏了virtual
并且growl
是虚拟的)。
或者你可以function
将参数作为参数 Cat&
,IMO 这是最干净的方法。
每只
家猫都是猫,但每只猫都不是家猫。因此,如果您打算学习多态性(从您的代码中,它看起来像这样),请记住,允许转换为基类指针/引用,从基类指针/引用转换为子类并不容易。您必须显式使用dynamic_cast。
但是,除此之外,您的代码还有许多其他问题。咆哮的方法应该声明为虚拟的,你应该为它指定一个返回类型,你不能从外部调用私有成员函数((cats[0])->growl() 不会编译)。
相关文章:
- C++:将值赋值给原始数据类型(例如布尔值)是原子操作吗?
- 使用字节向量作为其他类型的原始存储是一种好的做法吗
- 为什么重建的地图类型与原始地图类型不同?
- BoostSpirit.Qi-针对原始数据类型进行边界检查
- CAN模板类型推理考虑原始操作类型转换
- 请参阅Watch-Window中的原始类型定义
- 是仅使用get或toplown的原始类型的线程安全性的威胁
- 将 std::conditional 与不可转换类型(原始与指针)一起使用
- 如何在用户修改后使用旧版驱动程序中的 PE 标头获取原始文件类型
- 用于操作原始内存的正确数据类型
- 如何调节类模板和原始类型模板
- 如何复制包含非原始类型的阵列
- 原始类型的强类型(BOOST_STRONG_TYPEDEF没有切割)
- c中的neo4j-client,在语句中编码的原始类型(即int)
- 幻影类型是否与原始类型具有相同的对齐方式
- 通过参考传递原始类型是适得其反的吗?
- 统一功能使用模板专业化和接口来调用实例和原始类型
- 返回与原始模板类型不同的模板时没有匹配函数
- NDK带有JNI的ndk,使用返回类型的非原始类型调用方法
- 测试与C 原始数据类型上同步锁定的需求