纯虚函数会被赋予默认函数吗?

Will the pure virtual function be assigned a default function?

实例化class 时,会创建一个虚拟table 指针以指向其虚拟table。并且每个虚函数都分配了一个函数地址。

纯虚函数会分配默认函数地址吗?

class base {
public:
   virtual void func() = 0;
};

class derived : public base {
public:
   virtual void func() {
      cout << "derived func" << endl;
   }
};

int main()
{
   base *ptr = new derived();
   delete ptr;
   ptr->func();
   return 0;
}

我有 运行 VS2017 上的演示,但发生了错误“performed a bad memory access”。 我知道在Linux系统下会调用“__cxa_pure_virtual”。那么如何实现我的“__cxa_pure_virtual”呢?以及如何将函数地址分配给我的纯函数?

跟随指向已删除对象的指针是未定义的行为。

有时会运行,有时会崩溃,有时会格式化您的硬盘。

在机器代码的典型实现中,删除的对象将其内存标记为可回收,此标记可能会也可能不会修改对象所在位置的数据。在某些时候,另一个分配将重用该内存。

vtable 指针存储在对象的前面附近,可以随时覆盖。或者也许没有被覆盖。也许它得到一个指向不同虚表的指针,该虚表在那里具有删除目录功能。或者,编译器可能会进行整个程序优化,并证明每个指向基的有效指针都是指向派生的指针,并对每个调用进行去虚拟化。

调用已删除对象中的方法是未定义的行为,因此原则上任何事情都可能发生,这是你的错,但我们可以解释原因 你看到了这种行为。

首先,当你有一个纯虚函数时,编译器可以将空指针存储到 vtable 中,当你调用该函数时它会崩溃。您的编译器很有用,它存储了一个指向名为 __cxa_pure_virtual 的函数的指针,该函数旨在在您调用它时崩溃。所以这个函数的崩溃告诉你崩溃是由于调用了一个纯虚函数。这样既方便调试,也更安全,有定义的crash。

其次你删除了 ptr。删除派生对象运行派生 class 析构函数,然后将对象转换为基础 class 对象,然后调用基础 class 析构函数。 Ptr 在其 vtable 中有一个指向真正 func() 的指针,但是这三个步骤的 csecond 将其替换为指向 __cxa_pure_virtual 的指针。该对象的内存似乎已释放但未被覆盖,因此您的代码设法调用了纯虚函数。

而你绝对百分百无法实现__cxa_pure_virtual。它已经实施。它在调用时崩溃,这是故意的,应该是这样。