继承和隐式类型转换

时间:2012-12-01 10:27:24

标签: c++

假设我有以下三个类:

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)一样投射它,但编译器给了我一个警告,我遇到了运行时错误。

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

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

下面     d.setOwner((动物)及; H)

您尝试将指针类型设置为对象类型。你不能这样做。

正确的投射到Animal类的方法是

d.setOwner((Animal*)&h)

但是你

d.setOwner(&h);

有效,因为如果需要,C ++中的指针会自动转换为基类。不需要显式转换为Animal *。

答案 2 :(得分:1)

当其他人离开时,没有必要将派生的*转换为基础*

但是没有人回答警告的问题。 是的,有一个临时动物创建。而不是转换指针,您将对象本身从人类所有者转移到Animal。这导致从人类所有者创建临时Animal。该临时的地址被传递给set函数。当安装者返回临时人类消遣者时,可怜的狗主人指针无效。

所以请务必阅读警告。如果你不理解他们认为他们是错误。

另一个问题 - 避免构造函数元素和成员使用相同的名称,或者有一天你会很难学习这条规则。