C++箴言:避免构造或析构
函数
excel方差函数excelsd函数已知函数 2 f x m x mx m 2 1 4 2拉格朗日函数pdf函数公式下载
中调用虚函数
考研屋 www.kaoyanwu.com
提供各大机构考研、公务员、四六级辅导视频课程
如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉。但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼。
正文
我想以重复本文的主
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
开篇:不要在类的构造或者析构函数中调用虚函数,因为这种调用不会如你所愿,即使成功一点,最后还会使你沮丧不已。如果你以前是一个Java或者C#程序员,请密切注意本节的内容-这正是C++与其它语言的大区别之一。
假设你有一个为股票交易建模的类层次结构,例如买单,卖单,等等。为该类交易建立审计系统是非常重要的,这样的话,每当创建一个交易对象,在审计登录项上就生成一个适当的入口项。这看上去不失为一种解决该问题的合理方法:
class Transaction {// 所有交易的基类public: Transaction(); virtual void logTransaction()
const = 0;//建立依赖于具体交易类型的登录项 ...};Transaction::Transaction() //实现基类的构造函数{ ... logTransaction(); //最后,登录该交易} class BuyTransaction: public Transaction
{ // 派生类public: virtual void logTransaction() const; //怎样实现这种类型交易的登录, ...};class SellTransaction: public Transaction { //派生类public: virtual void logTransaction() const; //怎样实现这种类型交易的登录, ...};
现在,请分析执行下列代码调用时所发生的事情:
BuyTransaction b;
很明显,一个BuyTransaction类构造器被调用。但是,首先调用的是Transaction类的构造器-派生类对象的基类部分是在派生类部分之前被构造的。Transaction构造器的最后一行调用了虚函数logTransaction,但是奇怪的事情正是在此发生的。被调用函数logTransaction的版本是Transaction中的那个,而不是BuyTransaction中的那个-即使现在产生的对象的类型是BuyTransaction,情况也是如此。在基类的构造过程中,虚函数调用从不会被传递到派生类中。代之的是,派生类对象表现出来的行为好象其本身就是基类型。不规范地说,在基
。 类的构造过程中,虚函数并没有被”构造”
对上面这种看上去有点违背直觉的行为可以用一个理由来解释-因为基类构造器是在派生类之前执行的,所以在基类构造器运行的时候派生类的数据成员还没有被初始化。如果在基类的构造过程中对虚函数的调用传递到了派生类,派生类对象当然可以参照引用局部的数据成员,但是这些数据成员其时尚未被初始化。这将会导致无休止的未定义行为和彻夜的代码调试。沿类层次往下调用尚未初始化的对象的某些部分本来就是危险的,所以C++干脆专业提供提供各大机构考研、公务员、四六级辅导视频课
考研屋 www.kaoyanwu.com
提供各大机构考研、公务员、四六级辅导视频课程
不让你这样做。
事实上还有比这更具基本的要求。在派生类对象的基类对象构造过程中,该类的类型是基类类型。不仅虚函数依赖于基类,而且使用运行时刻信息的语言的相应部分(例如,dynamic_cast(参见Item 27)和typeid)也把该对象当基类类型对待。在我们的示例中,当Transaction的构造器正运行以初始化BuyTransaction对象的基类部分时,该对象是Transaction类型。在C++编程中处处都这样处理,这样做很有意义:在基类对象的初始化中,派生类对象BuyTransaction相关部分并未被初始化,所以其时把这些部分当作根本不存在是最安全的。 在一个派生类对象的构造器开始执行之前,它不会成为一个派生类对象的。
在对象的析构期间,存在与上面同样的逻辑。一旦一个派生类的析构器运行起来,该对象的派生类数据成员就被假设为是未定义的值,这样以来,C++就把它们当做是不存在一样。一旦进入到基类的析构器中,该对象即变为一个基类对象,C++中各个部分(虚函数,dynamic_cast运算符等等)都这样处理。
在上面的示例代码中,Transaction构造器直接调用了一个虚函数-这明显地破坏了本文所强调的原则。这种破坏性非常容易觉察
考研屋www.kaoyanwu.com :提供各大机构考研、公务员、四六级辅导视频课程 专业提供提供各大机构考研、公务员、四六级辅导视频课