c++ - Visual Studio 2008 : Polymorphic behavior of C++

标签 c++ polymorphism

我正在尝试了解 C++ 代码中的多态行为。看到下面程序的输出,我感到很惊讶。

以下代码的输出我预计在以下编程语句中会出现一些编译错误/崩溃。但是这个程序的输出让我很惊讶。

p = (Class1*) &object3;
p->f();
p->g();

我不明白为什么。我正在使用 Visual Studio 2008。

代码片段。

#include "stdafx.h"
#include <iostream>

using namespace std;

class Class1
{
   public:
      virtual void f()
      {
    cout << "Function f() in Class1\n";
      }

     void g()
     {
    cout << "Function g() in Class1\n";
     }
 };


 class Class2
 {
    public:
   virtual void f()
   {
    cout << "Function f() in Class2\n";
   }

   void g()
   {
    cout << "Function g() in Class2\n";
   }
 };


class Class3
{
    public:

    virtual void h()
    {
    cout << "Function h() in Class3\n";
    }
  };


  int _tmain(int argc, _TCHAR* argv[])
  {
   Class1 object1, *p;
   Class2 object2;
   Class3 object3;

  p = &object1;

  p->f();
  p->g();

  p = (Class1*) &object2;

  p->f();
  p->g();

  p = (Class1*) &object3;

  p->f();
  p->g();

  //p->h();      Compilation error

  return 0;

   }

O/P:

Class1 中的函数 f()

Class1 中的函数 g()

Class2 中的函数 f()

Class1 中的函数 g()

Class3 中的函数 h()

Class1 中的函数 g()

最佳答案

你正在使用一个邪恶的 C 风格转换,在这种情况下相当于 reinterpret_cast,将一个指针指向一个类并假装它指向一个不相关的类。

I was expecting some compilation error/crash

没有编译错误,因为你故意阻止编译器检查类型转换 - 这就是 reinterpret_cast 的目的,也是避免它的原因(C 风格的转换更是如此)所以)除非真的有必要。可能会发生崩溃或任何其他类型的未定义运行时行为。

在您的情况下,类布局似乎足够相似,即使指针类型完全错误,虚函数调用也能成功。这并不奇怪,因为您的类定义都非常相似;但这在很大程度上不是保证的行为,原则上它可能会以许多灾难性的方式失败。

如果你想要多态行为,那么 Class2Class3 应该继承自 Class1。指针转换将在没有转换的情况下有效,并且多态行为将得到很好的定义 - f() 将根据对象类型进行虚拟分派(dispatch),而 g() 根据指针类型非虚拟。

关于c++ - Visual Studio 2008 : Polymorphic behavior of C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14941723/

相关文章:

c++ - 如何从一系列快照中编码视频?

c# - 继承和 'Curiously Recurring Template Pattern'

c++ - 通过引用传递派生类到以基类为参数的函数

c++ - 如何在C++中实现继承并解决错误 "parent class is not accessible base of child class"?

c++ - std::regex:匹配由数字和空格组成的字符串,并提取数字。怎么样?

c# - 将以空字符结尾的字符串列表从外部函数返回到 .NET

java - 如何搜索数组列表/多态数组的数组列表

language-agnostic - 我应该使用像 IEnumerable 这样的接口(interface),还是像 List<> 这样的具体类

c++11 - unique_ptr<Derived> 到 unique_ptr<Base> 是否自动向上转换?

c++ - 在模板类中声明与 friend 相同的模板类?