C++中“Virtual outside class declaration ”解决办法
(1)定义两个类:Shape类和Circle类,Circle类共有继承Shape类,借此演示虚析构函数的作用。
Shape类头文件
#ifndef SHAPE_H
#define SHAPE_H
#include <iostream>
using namespace std;
class Shape
{
public:
Shape();
virtual ~Shape();
virtual double calcArea();
//private:
};
#endif
Shape类实现
#include "Shape.h"
#include <iostream>
using namespace std;
Shape::Shape()
{
cout<<"Shape()"<<endl;
}
Shape::~Shape()
{
cout<<"~Shape()"<<endl;
}
double Shape::calcArea()
{
cout<<"shape-calcArea()"<<endl;
return 0;
}
Circle类头文件
#include "Shape.h"
class Circle:public Shape
{
public:
Circle(double r);
~Circle();
double calcArea();
protected:
double m_dR;
};
Circle类实现
#include "Circle.h"
#include <iostream>
using namespace std;
Circle::Circle(double r)
{
cout<<"Circle()"<<endl;
m_dR=r;
}
Circle::~Circle()
{
cout<<"~Circle()"<<endl;
}
double Circle::calcArea()
{
cout<<"Circle--Circle()"<<endl;
return 3.14*m_dR*m_dR;
}
main函数
#include <iostream>
#include <stdlib.h>
#include "Circle.h"
using namespace std;
int main(void)
{
//在堆上实例化一个Shape类型的对象指针,以子类的对象给父类的
//对象指针初始化。
Shape *p1=new Circle(5);
//使用该指针访问calcArea()函数,若Shape类的calcArea函数不是虚函数,
//则调用Shape类的该函数,若是虚函数,则调用子类的calcArea函数。
p1->calcArea();
delete p1;
p1=NULL;
system("pause");
return 0;
}
运行结果:
(2)错误示例
虚析构函数使用错误:
class Shape
{
public:
Shape();
virtual ~Shape();
virtual double calcArea();
//private:
};
virtual Shape::~Shape()
{
cout<<"~Shape()"<<endl;
}
解释:Take the “virtual”s out of the cpp file. You only need to specify it in the class definition (in the header file). After that, the compiler knows that it’s virtual.
也就是说你只需要在类的定义中将成员函数声明为 virtual类型即可,而不用在成员函数的实现中加入 virtual关键字。
(3)定义父类的指针指向子类的对象时,先调用父类的构造函数再调用子类的构造函数,释放内存时,若父类的析构函数不是虚析构函数,则只释放调用父类的析构函数而不调用子类的析构函数,从而造成内存泄漏。