Pure Virtual Function Call

这里有详细的解释
https://www.codeproject.com/Articles/14879/Pure-Virtual-Function-Call

当一个对象包含一个纯虚函数(一个未实现的函数)时,这个对象根本不能被构造,因此纯虚函数不能被称为全部。试试下面的代码:

class Parent
{
public:
 Parent()
 {
 }
 ~Parent()
 {
  ClearALL();
 }

 void ClearALL()
 {
  ThePure();
 }

 virtual bool ThePure() = 0 ;
};

void main()
{
 Parent P; 
/*error C2259: 'Parent' : cannot instantiate abstract class due to following members: Parent::ThePure(void)*/
}

等等……可以做到…

那么,一个纯虚函数是如何被调用的呢?为了生产它,让我们继续工作,从父类继承一个新的类。我们叫它孩子吧。因此,我们有以下代码:

class Parent
{
public:
 Parent()
 {
 }
 ~Parent()
 {
  ClearALL();
 }

 void ClearALL()
 {
  ThePure();
 }

 virtual bool ThePure() = 0 ;
};


class Child : public Parent
{
public:
 Child()
 {
 }

 ~Child()
 {
 }

 /* The implementation of the pure virtual function */
 virtual bool ThePure() 
 {
  return true;
 }

};


void main()
{
 Child c;
}

现在,我们对我们所做的多态性很满意,然后运行我们的程序,然后得到“纯虚拟函数调用”的震撼。

为了分析这一点,让我们假设一个纯虚函数。调用该函数thepure()但版本,没有实现我们应该从父类别对象并调用函数把它像:

Parent P;
P.ThePure(); //Compilation Error!

这当然是不可能的,但等等,这是可能的。怎么用????

我们都知道从面向对象的概念来看,当一个对象被破坏时,它被称为析构函数,然后是它的父类的析构函数等等,直到我们到达该家族的第一个父节点,然后销毁过程就完成了。因此,如果您检查了上面的代码,就会看到在父析构函数中,我们调用一个函数,函数反过来调用一个纯虚函数。在父代码中写这是合法的,因为在运行时不可能有它的实例。当然,代码将运行在类型子对象中(因为父代不能完全按照我们所说的构造)。但是此时(父析构函数内部)被调用并完成了子析构函数,因此,我们现在没有一个类型子对象,但是当前对象(只被破坏)是类型父类,所以析构函数中的所有调用都是对这个对象中函数的调用。因此,可以得到纯虚函数。

编译器有时会有帮助

现在,你要问上面的代码的问题是,为什么我不叫纯虚函数直接与其说clearall()反过来调用它的析构函数。答案是幸福的消息。编译器很聪明,可以检测出这样的错误(为什么?)并发出链接错误。但是如果像这样间接调用它,编译器将对调用链中的函数视而不见,获得纯虚函数。

我在vc++ 6和vc++ 2003下编译了这个代码,结果也一样。

结论

因此,为了避免这个错误,您不应该调用析构函数中的函数,调用函数在这个对象中没有实现的功能。

你可能感兴趣的:(C/C++以及新特性)