Effective C++(9) 构造函数调用virtual函数会发生什么
不要在构造函数和析构函数中调用virtual函数,因为这样的调用不会带来你预想的结果。
让我先来看一下在构造函数里调用一个virtual函数会发生什么结果
Demo
class Transaction {
public:
Transaction();
virtual void logTransaction() const = ;
};
Transaction::Transaction()
{
logTransaction();
}
//void Transaction::logTransaction() const //第一次编译时,注释掉该段代码
//{
// std::cout << "Transaction called" << std::endl;
//}
class BuyTransaction: public Transaction
{
public:
virtual void logTransaction() const;
};
void BuyTransaction::logTransaction() const
{
std::cout << "BuyTransaction called" << std::endl;
}
//执行下面的语句会发生什么事情?
BuyTransaction b;


- 父类构造函数先调用,此时子类的局部成员变量还没准备好,这时如果将virtual函数下降至子类阶层,那么使用未初始化的部分可能会引起不明确的行为,所以C++直接禁止了这种行为,因此会出现上面的链接错误。
- 在子类的父类部分被构造期间,virtual函数并不认为是virtual函数,因为在初始化子类的父类部分时,编译器认为当前的对象是父类型,同时,直接认为子类部分是不存在的,因为子类成分并没有被初始化。
/** main.h **/
#include<iostream>
#include<string>
class Transaction {
public:
explicit Transaction(const std::string& logInfo);
void logTransaction(const std::string& logInfo) const; // 不再是虚函数
};
Transaction::Transaction(const std::string& logInfo)
{
logTransaction(logInfo);
}
void Transaction::logTransaction(const std::string& logInfo) const
{
std::string s = logInfo;
std::cout << s << std::endl;
}
class BuyTransaction: public Transaction
{
public:
BuyTransaction(const std::string& logInfo);
};
BuyTransaction::BuyTransaction(const std::string& logInfo):Transaction(logInfo) // 把信息传递给父类,通过父类打印出log
{
std::cout << "BuyTransaction called" << std::endl;
} /** main.cpp **/
#include<iostream>
#include"main.h"
int main()
{
BuyTransaction b("hello world");
system("Pause");
return ;
}

Effective C++(9) 构造函数调用virtual函数会发生什么的更多相关文章
- C++构造函数调用虚函数的后果
#include <iostream> class cx { public: virtual void func() { std::cout << "func&quo ...
- Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: ...
- Effective C++ -----条款09:绝不在构造和析构过程中调用virtual函数
在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数的那层).
- Effective C++ .09 不在构造和析构过程中调用virtual函数
看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtu ...
- Effective C++ 条款九、十 绝不在构造和析构过程中调用virtual函数|令operator=返回一个reference to *this
1.当在一个子类当中调用构造函数,其父类构造函数肯定先被调用.如果此时父类构造函数中有一个virtual函数,子类当中也有,肯定执行父类当中的virtual函数,而此时子类当中的成员变量并未被初始 ...
- NO.8:绝不在构造或者析构过程中调用virtual函数
在构造和析构执行期间不要调用virtual函数,因为这类调用从不会下降至derived class(比起当前执行构造函数和析构函数) 如果在base class 构造函数或者析构函数调用virtual ...
- 09——绝不在构造和析构函数中调用virtual函数
在base class构造期间,virtual函数不是virtual函数. 构造函数.析构函数中不要调用virtual函数.
- [Effective JavaScript 笔记]第18条:理解函数调用、方法调用及构造函数调用之间的不同
面向对象编程中,函数.方法.类的构造函数是三种不同的概念. JS中,它们只是单个构造对象的三种不同的使用模式. 三种不同的使用模式 函数调用 function hello(username){ ret ...
- 条款9:不要在构造和析构过程中调用virtual函数
如下是一个股票交易的例子: class Transaction // 交易的基类 { public: Transaction(); ; // 用于记录交易日志 }; Transaction::Tran ...
随机推荐
- 四大组件之Activity Task任务栈4种启动模式
1.启动模式 standard,创建一个新的Activity. singleTop,栈顶不是该类型的Activity,创建一个新的Activity.否则,onNewIntent. singleTask ...
- Microsoft Power BI Desktop概念学习系列之Microsoft Power BI Desktop是什么?
不多说,直接上干货! 官网 https://powerbi.microsoft.com/zh-cn/desktop/ Microsoft Power BI Desktop是什么? https://p ...
- 【LeetCode题解】349_两个数组的交集
目录 [LeetCode题解]349_两个数组的交集 描述 方法一:两个哈希表 Java 实现 类似的 Java 实现 Python 实现 类似的 Python 实现 方法二:双指针 Java 实现 ...
- [Mysql]——用户管理
登录和退出 > mysql -h 参数后面接hostname或者hostIP -P 参数后面接Mysql服务的端口号,通过指定的端口号来进行连接 -u 参数后面接username用户名 -p ...
- [Mysql 查询语句]——查询字段
查询所有字段 select * from 表名; 可以用 * 号代表所有字段 select * from vendors; +---------+----------------+--- ...
- Windows下编程--模拟时钟的实现
windows下编程--模拟时钟的实现: 主要可以分为几个步骤: (1) 编写按键事件处理(启动和停止时钟) (2) 编写时钟事件处理,调用显示时钟函数 (3) 编写显示时钟函数,要调用显 ...
- centos下对文件某些特定字符串分组统计出现次数
假如现有数据: { "@timestamp": "2018-10-13T21:55:58+08:00", "remote_addr": &q ...
- shell脚本生成服务器密码
#!/bin/bash len=90 str=(a b c d e f g h i j k l m n o p q r s t u vw x y z A B C D E F G H I J K L M ...
- 类class思维导图
- 【Chromium】GPU进程启动流程
本篇文档以gpu进程的创建和启动为例,讲述chormium如何启动一个browser进程的子进程 PS:本文使用的chromium代码版本为71 前言 GPU进程的启动时机是由browser进程负责的 ...