effective c++条款09:绝不在构造和析构过程中调用virtual函数

版权声明:转载请注明出处,谢谢!!! https://blog.csdn.net/qhdhnbd110/article/details/83409414
#include <iostream>
using namespace std;

class BaseClass
{
public:
	BaseClass()
	{
		cout << "BaseClass" << endl;
	}
	~BaseClass()
    {
        cout << "~BaseClass" << endl;
    }
};

class DerivedClass:public BaseClass
{
public:
	DerivedClass:public ()
	{
		cout << "DerivedClass:public " << endl;
	}
	~DerivedClass()
    {
        cout << "~DerivedClass" << endl;
    }
};
int main()
{
	DerivedClass dc;
	return 0;
}

首先大家思考一下,上面这段代码输出语句的执行顺序?

运行结果:

这说明BaseClass的构造函数是先于DerivedClass的构造函数的,而DerivedClass的析构函数是先于BaseClass的。

那么下面这段代码编译后会发生什么?

#include <iostream>
using namespace std;

class BaseClass
{
public:
	BaseClass()
	{
		PrintWho();
	}
	virtual ~BaseClass()
    {
        
    }
public:
	virtual void PrintWho() = 0;
};

class DerivedClass:public BaseClass
{
public:
	DerivedClass()
	{
		
	}
	~DerivedClass(){}
public:
	void PrintWho()
	{
		cout << "DerivedClass" << endl;
	}
};
int main()
{
	DerivedClass dc;
	return 0;
}

答案: 

 为什么出现这种情况已经显而易见了,链接器找不到PrintWho函数的定义,BaseClass中并没有给出具体实现。虽然在DerivedClass中给出了具体实现,但是BaseClass的构造是先于DerivedClass构造的。

但是如果改成这样:

#include <iostream>
using namespace std;

class BaseClass
{
public:
	BaseClass()
	{
		PrintWho();
	}
	virtual ~BaseClass()
    {
        
    }
public:
	virtual void PrintWho()
	{
		cout << "BaseClass" << endl;
	}
};

class DerivedClass:public BaseClass
{
public:
	DerivedClass()
	{
	}
	~DerivedClass(){}
};
int main()
{
	DerivedClass dc;
	return 0;
}

程序就可以正常运行。 

所以说,与其说“绝不在构造和析构过程中调用virtual函数”,不如说“不要在BaseClass的构造和析构中调用纯虚函数或者是未在BaseClass中定义的虚函数”。

猜你喜欢

转载自blog.csdn.net/qhdhnbd110/article/details/83409414