当我们尝试访问带有和没有虚函数的下行指针时发生了什么

时间:2012-10-18 13:56:36

标签: c++ inheritance casting virtual

这是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;
}

将显示代码     一个     “停” 发生了什么?如果重要的是反对指针指向。

它假设要显示    一个    乙 而不是腐败。

发生了什么事?

我真的很感激任何建议或指示。非常感谢。

3 个答案:

答案 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” cv2 D“,其中D是从B派生的类,如果从”指向D的指针“转换为”指向{{的指针“的有效标准转换1}}“存在, cv2 cv1 B具有相同的cv资格,或更高的cv资格   既不是B的虚基类,也不是D的虚基类的基类。空指针值将转换为目标类型的空指针值。如果“指向 cv1 D的指针”的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也不会起作用。它在这种特殊情况下起作用的原因是AB的vtable完全相同。