这是2个代码 第一:
#include<iostream>
using namespace std;
class A{
public:
virtual void f()
{
cout<<"A"<<endl;
}
};
class B: public A{
public:
virtual void f()
{
cout<<"B"<<endl;
}
};
int main()
{
A* pa=new A();
B* pb=new B();
A* upCastpa= static_cast<A*>(pb);
B* downCastpb=static_cast<B*>(pa);
upCastpa->f();
downCastpb->f();
return 1;
}
一个显示器
B
A
因此,我认为真正重要的是指向指针的反对意见。 但是,如果我删除虚拟表单A :: f(),就像这样;
#include<iostream>
using namespace std;
class A{
public:
void f()
{
cout<<"A"<<endl;
}
};
class B: public A{
public:
virtual void f()
{
cout<<"B"<<endl;
}
};
int main()
{
A* pa=new A();
B* pb=new B();
A* upCastpa= static_cast<A*>(pb);
B* downCastpb=static_cast<B*>(pa);
upCastpa->f();
downCastpb->f();
return 1;
}
将显示代码 一个 “停” 发生了什么?如果重要的是反对指针指向。
它假设要显示 一个 乙 而不是腐败。
发生了什么事?
我真的很感激任何建议或指示。非常感谢。
答案 0 :(得分:2)
无论是否存在virtual
功能:
A* pa=new A();
B* downCastpb=static_cast<B*>(pa);
导致未定义的行为。
当您使用static_cast
将对象强制转换为不属于的类型时,会导致未定义的行为。一旦你有一个产生未定义行为的代码,尝试找出观察到的输出的推理是没用的。编译器可以自由地显示任何行为,崩溃,奇怪的结果或绝对精细的工作代码。您完全受编译器的支配。
参考:
C ++ 11 Standard 5.2.9 [expr.static.cast]
类型为“指向 cv1
B
的指针”的prvalue,其中B
是类类型,可以转换为类型为“指向的指针的prvalue” cv2D
“,其中D
是从B
派生的类,如果从”指向D
的指针“转换为”指向{{的指针“的有效标准转换1}}“存在, cv2 与 cv1 和B
具有相同的cv资格,或更高的cv资格 既不是B
的虚基类,也不是D
的虚基类的基类。空指针值将转换为目标类型的空指针值。如果“指向 cv1D
的指针”的prvalue指向 到B
实际上是B
类型对象的子对象,结果指针指向封闭对象 类型为D
。否则,演员的结果未定义。
答案 1 :(得分:0)
这是多态性。您应该将virtual void f()
写入基类A并将void f()
写入继承者类B
答案 2 :(得分:0)
删除第一个virtual
,可以有效防止它进入vtable。这意味着班级A
的vtable现在为空。但是,因为类B
确实有一个虚函数,所以它在vtable中有一个条目。
因此,当您将A*
向下转换为B*
,然后通过它调用f
时,该调用将在空的vtable中查找函数f
。没有找到它,它会抱怨代码损坏。
在实践中,在一般情况下,您的示例1也不会起作用。它在这种特殊情况下起作用的原因是A
和B
的vtable完全相同。