Effective C++学记之09 绝不在构造和析构过程中调用virtual函数
来源:互联网 发布:subtitle软件 编辑:程序博客网 时间:2024/05/16 15:05
在构造和析构期间不要调用virtual函数,因为这类调用从不下降至子类。
例:股票交易买进卖出审计日志系统。
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;被执行时:
首先调用父类的构造函数。在构造函数中调用的virtual函数是父类的版本,绝不是子类的版本!
父类构造期间virtual函数绝不会下降到子类阶层。是的,“在父类构造期间,virtual函数不是virtual函数”^-^
理由:父类构造函数早于子类构造,此时子类的成员变量尚未初始化。若能下降到子类的virtual必然要取子类的成员变量。
有可能导致不明确行为。
在父类的构造期间,对象的类型是父类而非子类。不仅仅是virtual函数,日哟使用运行期类型信息(例dynamic_Cast和typeid),也会视为父类类型。
为了确保子类版本的logTransaction被调用,可以有以下方案:
在父类中将logTransaction改为non-virtual,并要求子类构造函数传递必要信息给Transaction构造函数。
class Transaction{
public:
explicit Transaction(const std::string& logInfo);
void logTransaction(const std::string& logInfo) const;
...
};
Transaction::Transaction(const std::string& logInfo)
{
...
logTransaction(logInfo); // 志记交易
}
class BuyTransaction:public Transaction{
public:
BuyTransaction(parameters):Transaction(createLogString(parameters))
{...}
...
private:
static std::string createLogString(paramerters); //令次函数为static避免了意外指向“初始未成熟之BuyTransaction对象内尚未初始化成员变量”。
};
例:股票交易买进卖出审计日志系统。
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;被执行时:
首先调用父类的构造函数。在构造函数中调用的virtual函数是父类的版本,绝不是子类的版本!
父类构造期间virtual函数绝不会下降到子类阶层。是的,“在父类构造期间,virtual函数不是virtual函数”^-^
理由:父类构造函数早于子类构造,此时子类的成员变量尚未初始化。若能下降到子类的virtual必然要取子类的成员变量。
有可能导致不明确行为。
在父类的构造期间,对象的类型是父类而非子类。不仅仅是virtual函数,日哟使用运行期类型信息(例dynamic_Cast和typeid),也会视为父类类型。
为了确保子类版本的logTransaction被调用,可以有以下方案:
在父类中将logTransaction改为non-virtual,并要求子类构造函数传递必要信息给Transaction构造函数。
class Transaction{
public:
explicit Transaction(const std::string& logInfo);
void logTransaction(const std::string& logInfo) const;
...
};
Transaction::Transaction(const std::string& logInfo)
{
...
logTransaction(logInfo); // 志记交易
}
class BuyTransaction:public Transaction{
public:
BuyTransaction(parameters):Transaction(createLogString(parameters))
{...}
...
private:
static std::string createLogString(paramerters); //令次函数为static避免了意外指向“初始未成熟之BuyTransaction对象内尚未初始化成员变量”。
};
- Effective C++学记之09 绝不在构造和析构过程中调用virtual函数
- Effective C++:条款09:绝不在构造和析构过程中调用virtual函数
- 读书笔记《Effective C++》条款09:绝不在构造和析构过程中调用virtual函数
- Effective C++笔记09:绝不在构造函数和析构过程中调用virtual 函数
- 【Effective c++】条款09:绝不再构造和析构过程中调用virtual函数
- Effective C++ 读书笔记 条款09:绝不在构造和析构过程中调用virtual函数
- effective C++ 09_绝不在构造和析构过程中调用virtual函数 读书笔记
- Effective C++ Item 9 绝不在构造和析构过程中调用virtual函数
- Effective C++ Item 9 绝不在构造和析构过程中调用virtual函数
- effective c++绝不在构造和析构过程中调用virtual函数
- effective c++条款9(绝不在构造和析构过程中调用virtual函数)
- Effective C++ 条款9:绝不在构造和析构过程中调用virtual函数
- Effective C++——》条款9:绝不在构造和析构过程中调用virtual函数
- Effective C++读书笔记之九:绝不在构造和析构过程中调用virtual
- Effective C++ 笔记之六 绝不在构造和析构函数中调用virtual函数
- 《Effect C++》学习------条款09:绝不在构造和析构过程中调用virtual函数
- Effective C++ Item 09-绝不在构造函数和析构函数中调用virtual函数
- Effective c++学习笔记——条款09:绝不在构造和析构过程中调用virtual函数
- linux文件大写改名文件小写
- race condition 竞态条件
- delphi中Record和Packed Record区别
- ubuntu11.10 删除UNITY 侧边栏
- 文件分类、合并和分割(sort,uniq,join,cut,paste,split)
- Effective C++学记之09 绝不在构造和析构过程中调用virtual函数
- C++中的hash Map
- 自定义Button 实现Flex Button 描边效果。
- Oracle oradebug 命令 使用说明
- Ubuntu下默认sh报错的问题
- ios CGRect用法详解
- shell中多种求和方法
- java反射内容记录
- 把页面全部变灰色