1)我正在尝试运行这段代码:
#include <iostream>
struct A
{
virtual void m() {
std::cout << "A" ;
}
};
struct B : public A
{
void m() {
std::cout << "B";
}
};
int main()
{
A a;
B *b;
b = &(B)a;
b->m();
return 0;
}
如果你写在 main 中:
int main()
{
A *a;
B b;
a = &b;
a->m();
return 0;
}
一切都按预期工作。但问题是为什么不能将parent的类型强制转换为继承人的类型,反之亦然呢?类型转换机制在这里如何工作?或者是否仍然可以将父类型转换为子类型?
1)另一个问题,如果你这样写:
struct A
{
void m() {
std::cout << "A" ;
}
};
struct B : public A
{
void m() {
std::cout << "B";
}
};
int main()
{
A *a;
B b;
a = &b;
a->m();
return 0;
}
然后在对象 A 上调用 m()。但是对象 A 似乎不存在。那么我不清楚这个m()是在哪里调用的,如果一个A类型的对象不存在,是为哪个A类型的对象调用的?
子对象包含父对象,因此将子对象转换为父对象不是问题,可以隐式完成。
另一方面,父对象不知道它的子对象可以定义什么以及如何定义。他没有这样的信息。因此,不存在从父对象到任何子对象的隐式转换。
当没有虚函数时,调用的函数在编译时静态绑定到对象类型。
在这个节目中
指针的静态类型
a是 typestruct A,因此编译器绑定在该类型中声明的函数。其实对于虚函数也是一样的,就是编译器根据指针或者对象引用的静态类型来查找函数名。另一件事是函数调用是使用一种使用虚函数表的机制来执行的。该表的地址是在运行时动态解析的,尽管在一些简单的情况下,当静态和动态类型相同时,它可以在编译时解析。
允许将父母代为继承人,这称为
downcast,可以这样做,例如,像这样b = static_cast<B*>(&a);在您的第一个示例中,从语法的角度来看,由于 C++ 代码不正确,将出现编译错误
b = &(B)a;可能你打算这样写
b = (B*)&a;edit 编译错误,如前所述
Ant,不是在语法上,而是在C++语言的语义上这是 C 风格的强制转换——最好避免这种情况,在 C 的情况下
downcast更是如此——最好使用 C++ 中特殊且更安全的显式强制转换运算符(如前所述)但总的来说,
downcast在某些情况下这样会导致未定义的行为关于第三个问题 - 显示是
A因为父类中的这个函数不是虚函数 - 这是虚函数的主要含义 - 确保通过指向基类(父类)的指针调用继承人中重写的父方法,分别如果函数在基类中不是virtual,那么他会调用谢谢你!
我成熟了!下面的代码按预期输出 BB