#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
class baseC {
public:
baseC():str("baseClass"){}
~baseC() {
cout << str << endl;
}
virtual void print() { cout << str << endl; }
protected:
string str;
};
class derivedC :public baseC
{
public:
derivedC() :str2("derivedClass") { str = "111111"; }
~derivedC() {
cout << str2 << endl;
}
void print() { cout << "hhhhhhh" << endl; }
private:
string str2;
};
int main()
{
baseC * c = new derivedC;
c->print();
delete c;
return 0;
}
结果输出:
hhhhhhh
111111
即:如果基类的析构函数是非虚的,那么delete 基类指针 只会调用基类的析构函数。
乍看之下强调这个似乎没什么意义,每个比较熟练的C++使用者都会注意如果某个类可以被作为基类,那么可被覆写的方法和虚构函数都要加上virtual 关键字。
但万一这个类是库提供的呢?因此继承类的时候要问一下:我继承的这个Base类设计之初是不是允许被用来继承?如果不是,我写的类Derived继承Base之后需要注意什么,有什么风险,其实,如果希望继承的这个Base类的析构函数已经是非虚的了,其实已经表明了这个Base类设计之初就不希望被拿来用用作基类。这个库设计也非常不严谨,应该考虑换个库。
反过来思考,如果我写的某个类不希望被继承,如果表明呢?
用文档,不够强而有力,最有力的应该是从语法上入手。
参考方案一:用final关键字需(C++11支持)
1)声明base类的之后直接指定为final:
class baseC final
{
class body
};
2)将析构函数指定为final,virtual ~baseC() final;
此法也可用在任何不希望被覆写的方法上。
参考方案二:禁用默认构造函数:即将base()声明为非public的。
欢迎不同的见解的探讨。