继承和隐式类型转换

Inheritance and Implicit Type Casting

本文关键字:类型转换 继承      更新时间:2023-10-16

假设我有以下三个类:

class Animal {};
class Human : public Animal {};
class Dog : public Animal
{
public:
   void setOwner(Animal* owner) { this->owner = owner; }
private:
   Animal* owner;
};

为什么允许以下内容,究竟发生了什么?

Dog d;
Human h;
d.setOwner(&h); // ?

起初,我试图像这样d.setOwner(&(Animal)h)投射它,但编译器给了我一个警告,我遇到了运行时错误。

编辑:编译器给我的警告是"临时地址"。为什么会这样?

这里 d.setOwner((Animal)&h)

您尝试将指针类型大小写为对象类型。你不能这样做。

投射到动物类的正确方法是

d.setOwner((Animal*)&h)

但是你

d.setOwner(&h);

之所以有效,是因为如果需要,C++中的指针会自动强制转换为基类。不需要显式转换为动物*。

没有类型转换,但HumanAnimal。因此,任何作用于Animal*的接口都将接受Human* 。这同样适用于Animal&Human&。当然,他们只能看到对象界面的Animal部分。

由于其他人已经离开了,因此没有必要将派生*转换为base*

但没有人回答警告的问题。是的,创建了一个临时动物。而不是投射指针,而是将对象本身从人类所有者投射到动物。这导致从人类主人那里创造了一个临时动物。此临时地址已传递给 SET 函数。当二传手返回临时人类消失者时,可怜的狗主人指针无效。

因此,请务必阅读警告。 如果您不理解它们,请将它们视为错误。

另一个问题 - 避免构造函数元素和成员具有相同的名称,否则有一天你会以艰难的方式学习这个规则。