假设我有以下三个类:
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)
一样投射它,但编译器给了我一个警告,我遇到了运行时错误。
编辑:编译器给我的警告是“取临时地址”。为什么会这样?
答案 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函数。当安装者返回临时人类消遣者时,可怜的狗主人指针无效。
所以请务必阅读警告。如果你不理解他们认为他们是错误。
另一个问题 - 避免构造函数元素和成员使用相同的名称,或者有一天你会很难学习这条规则。