栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Effective C++ 条款9 不在构造和析构函数调用virtual函数

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Effective C++ 条款9 不在构造和析构函数调用virtual函数

在基类中构造函数中调用virtual函数带来不安全

#include 

class Transaction {
public:
    Transaction() { logTransaction(); }
 
    virtual void logTransaction() const = 0;
};

class BuyTransaction : public Transaction 
{
public:
    virtual void logTransaction() const{
        printf("BuyTransaction n");
    };
};
 
class SellTransaction : public Transaction 
{
public:
    virtual void logTransaction() const{
        printf("SellTransaction n");
    };
};

int main()
{
    SellTransaction *bb = new SellTransaction; //先调用Transaction构造函数,在调用SellTransaction构造函数
    return 0;
}

class Transaction的构造函数调用logTransaction()是有问题的,编译都不会通过。因为Transaction构造函数调用的是自己的virtual函数,main中SellTransaction *bb = new SellTransaction;的操作的流程是:调用SellTransaction的构造函数--->调用Transaction的构造函数。但在构造函数期间,基类与派生类并没有发生virtual的动态绑定,Transaction调用不到SellTransaction的logTransaction函数。简单的说:类构造函数中的virtual函数,不带virtual的性质,就是个普通函数。

为何基类的构造函数不能调用派生类的virtual函数呢?

(1)如果调用基类构造函数,这个时候可以调用派生类的virtual函数(也就是virtual函数绑定好了),那如果派生类的变量未初始化,那么这个派生类的virtual函数的调用将为程序带来不确定性,完全就是引入风险的操作,所以基类构造函数期间virtual函数不是virtual函数。

(2)同理适用于析构函数,当Derived类析构,base类再析构,base类的析构函数就不该能调用virtual函数,因为这个时候Derived类已经使用结束了,它的成员函数,变量再使用也是不安全的,所以Derived类析构之后,base类的析构函数不应该有virtual的使用,

如何在有Derived类对象被构造时,调用正确的base类函数呢?

通过Derived类向base类传递参数来调用base类的构造函数,说白了,就是在base类写歌函数,不要用virtual

class Transaction {
public:
    explicit Transaction(const std::string& logInfo) { logTransaction(logInfo) }
 
    void logTransaction(const std::string& logInfo) const; // non-virtual
};
 
 
class BuyTransaction : public Transaction 
{
public:
    BuyTransaction(parameters): Transaction(createLogString(parameters)) {}
private:
    static std::string createLogString(parameters);
};
 
class SellTransaction : public Transaction 
{
public:
    SellTransaction(parameters): Transaction(createLogString(parameters)) {}
private:
    static std::string createLogString(parameters);
};

总结:不要再构造,析构函数调用virtual函数。 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/702839.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号