C++陷阱:基类析构函数非虚,派生对象以基类指针析构

#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的。

欢迎不同的见解的探讨。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值