[英]C++ cannot initialize a variable of type 'char *' with an rvalue of type 'char'
[英]Why C++ cannot initialize a variable of type “derived class” with an rvalue of type “super class”?
请考虑以下代码:
class a
{
int a1;
public:
a()
{
printf("foo1\n");
}
};
class b : public a
{
int a2;
public:
b()
{
printf("foo2\n");
}
};
int main (int argc, const char * argv[])
{
b *instance = new a();
return 0;
}
它给出了错误:无法用“a*”类型的右值初始化“b*”类型的变量当我写的时候工作正常
a *instance = new b();
output 是:
foo1
foo2
有人可以解释一下原因吗? 我将非常感激:)
另一件事,如果我写
instance->~a();
以上return 0;
没有额外的事情发生。 这是因为构造函数只能调用一次吗?
b
是一个a
。
a
不是b
。
您可以将Giraffe
类型的实例放入Animal
类型的变量中。
但是,您不能将Animal
的实例放入Giraffe
类型的变量中(如果它是Porcupine
怎么办?)
根据定义,派生的 class 是可以做基础 class 可以做的超集的东西。 派生的 class 可以做基础 class 可以做的所有事情,但反之则不行。 因此,将派生的 class 视为基础 class 是有意义的,反之则不然。 例如:
class Animal {
void eat();
};
class Dog : public Animal {
void bark();
}
将Dog
视为通用Animal
是完全有道理的,但如果命令通用Animal
bark
,则没有任何合理的事情要做。
让我们更具体一点:
class Animal
{
int a1;
public:
Animal()
{
printf("Animal\n");
}
};
class Bat : public Animal
{
int a2;
public:
Bat()
{
printf("bat\n");
}
};
int main (int argc, const char * argv[])
{
Bat *instance = new Animal();
return 0;
}
你现在能明白为什么这可能无效了吗? 你用new Animal()
创建的可以是任何类型的 Animal。 将其分配给Bat
变量可能无效,因为它可能不是 bat。
由于a
不是 a b
,因此您不能将指向b
的指针分配给 a 类型a
object 。
由于b
是a
,因此它确实可以正常工作。
b
是 a 的a
。 但是, a
不是b
的类型。 如果b
包含其他成员,那么当您尝试访问它们时会发生什么,如果b
真的指的是 a 类型a
object 。
这不是一个安全的演员。
请始终记住这一点,您不能将基本 class object 分配给派生的 class 指针。 [派生 class 对象] 是 [基础 class 对象]。 反过来是不正确的。
问题在于“是”关系。 Object 的class a
不是 object 的class b
所以
b *instance = new a(); // won't work
这意味着您尝试将指向class b
的指针设置到不是 object class b
的东西上。 同时你可以做相反的事情:
a* instance = new b(); //will work
since objects of class b
are also objects of class a
and so here you would set a pointer to class a
onto something that is indeed an object of class a
.
你不能用a
代替 a b
因为a
没有b
的所有功能。 因此,进行这样的分配是没有意义的。
对于你的第二部分,99% 的时间你说delete var
来销毁用new
分配的东西,而不是显式调用析构函数,这是一个高级主题。
关于析构函数 -
如果操作数的 static 类型与动态类型不同,则它的 static 类型表现为基础 class 并且它的析构函数必须是虚拟的。
此外,派生 class 的指针/引用与基本 class 的指针/引用类型兼容。 但其他情况并非如此。 (无传递性)
在你的情况下 -
a *instance = new b(); // This should be correct way.
static instance
类型是a*
而动态类型是b*
。 因此, a
作为基础 class ,它的析构函数必须是virtual 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.