//############################################################################
/*
任何时候都不要在构造函数或析构函数中调用虚函数
*/
class dog {
public:
string m_name;
dog(string name) {m_name = name; bark();}
virtual void bark() { cout<< "Woof, I am just a dog " << m_name << endl;}
}; class yellowdog : public dog {
public:
yellowdog(string name) : dog(string name) {...}
virtual void bark() { cout << "Woof, I am a yellow dog " << m_name << endl; }
}; int main ()
{
yellowdog mydog("Bob");
} 输出:
Woof, I am just a dog Bob. /*
在构造的过程中,所有虚函数表现为非虚函数 为什么?
基类在派生类之前构造。
所以bark()的时候,yellowdog还没有构造 为什么Java中表现不一样? Java和C++在定义对象的生命周期上有一个基本的差异
Java: 所有成员在构造函数运行前被null初始化。生命周期在构造函数之前已经开始
C++: 构造函数负责初始化成员。生命周期在构造函数结束之后才开始 调用对象中还未被初始化的部分是继承危险的
调用对象中已经被delete的部分也是危险的
*/ /*
解决方法 1:
不使用多态,使用初始化参数来产生运行时差异
*/
class dog {
public:
...
dog(string name, string color) {m_name = name; bark(color);}
void bark(string str) { cout<< "Woof, I am "<< str << " dog " << m_name << endl;}
}; class yellowdog : public dog {
public:
yellowdog(string name):dog(name, "yellow") {}
}; int main ()
{
yellowdog mydog("Bob");
} 输出:
Woof, I am yellow dog Bob /*
解决方法 2:
使用私有静态成员函数,不同派生类可执行不同操作
*/
class dog {
public:
...
dog(string name, string woof) {m_name = name; bark(woof);}
dog(string name) {m_name = name; bark( getMyColor() );}
void bark(string str) { cout<< "Woof, I am "<< str << " dog " << m_name << endl;}
private:
static string getMyColor() {return "just a";}
}; class yellowdog : public dog {
public:
yellowdog(string name):dog(name, getMyColor()) {}
private:
static string getMyColor() {return "yellow";} //Why static?
}; int main ()
{
yellowdog mydog("Bob");
}
OUTPUT:
Woof, I am yellow dog Bob

C++进阶--构造函数和析构函数中的虚函数的更多相关文章

  1. 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数

    1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...

  2. 在构造函数和析构函数中调用虚函数------新标准c++程序设计

    在构造函数和析构函数中调用虚函数不是多态,因为编译时即可确定调用的是哪个函数.如果本类有该函数,调用的就是本类的函数:如果本类没有,调用的就是直接基类的函数:如果基类没有,调用的就是间接基类的函数,以 ...

  3. 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数

    关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...

  4. c++有关构造函数和析构函数中调用虚函数问题

    今天看了一道迅雷的笔试题目,然后引起一段思考,题目如下: 下列关于虚函数的说法正确的是()A.在构造函数中调用类自己的虚函数,虚函数的动态绑定机制还会生效.B.在析构函数中调用类自己的虚函数,虚函数的 ...

  5. EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

    9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...

  6. C++箴言:避免构造或析构函数中调用虚函数

    如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...

  7. 【C++】不要在构造函数或析构函数内调用虚函数

    这个问题来自于<Effective C++>条款9:永远不要在构造函数或析构函数中调用虚函数 . 假设有如下代码: class Transaction {// 所有交易的基类 public ...

  8. C++:构造函数和析构函数能否为虚函数

    原文:http://blog.csdn.net/xhz1234/article/details/6510568 C++:构造函数和析构函数能否为虚函数? 简单回答是:构造函数不能为虚函数,而析构函数可 ...

  9. C++构造与析构函数中调用虚函数的问题

    前些天想把以前写的内存池算法重写一遍,跨平台是第一目标,当时突发奇想,因为不愿意做成一大堆#if..#end,所以想利用C++的多态性,但是怎么让内存池完好退出却没想到自认为完美的方案.但是一个很偶然 ...

随机推荐

  1. PHP用户登录解析

    Web上的用户登录功能应该是最基本的功能了,可是在我看过一些站点的用户登录功能后,我觉得很有必要写一篇文章教大家怎么来做用户登录功能.下面 的文章告诉大家这个功能可能并没有你所想像的那么简单,这是一个 ...

  2. LG3275 【[SCOI2011]糖果】

    前言 我对差分约束有我个人独特的看法,写这题解既是与大家分享,又算作我对差分约束系统的总结. 浅谈差分约束 对于一些给出形如\(x_i-x_j\leq a\)不等式(差分约束)组,求\(x_t-x_s ...

  3. centos 7.0 lnmp成功安装过程(很乱)

    下载nginx [root@localhost src]# wget http://nginx.org/download/nginx-1.7.9.tar.gz --2015-01-24 12:55:2 ...

  4. deno学习四 docker 运行官方的一个http file server

    github 上已经有人搞了一个deno 的docker 镜像,是基于源码编译的,挺好的 所以结合官方的http server demo 使用docker 运行 环境准备 docker-compose ...

  5. 续drone 1.0 新界面调整

    接以前的内容,drone 最新发布的版本又有界面信息的调整了,更方便了. 环境准备 docker-compose 文件 version: '3' services: drone-server: ima ...

  6. STM32的ISP下载程序方式:

    STM32的板子的串口ISP下载方法:Boot0接到3.3V上,Boot1接到GND,对板子重新上电,STM32单片机重启的时候,会进入到ISP模式.

  7. MySQL 有用的查询语句

    查看指定数据库 db_name 的字符集和排序规则 USE db_name; SELECT @@character_set_database, @@collation_database; 显示索引信息 ...

  8. virtualBox 虚拟机下nginx设置不缓存静态文件不起作用解决办法

    最近开发的时候,调整js时会一直使用缓存文件,无法显示改动!nginx配置静态文件add_header Cache-Control no-cache;也不起作用,很苦恼! nginx配置代码:even ...

  9. js 控件样式显隐和赋值

    控制样式显示: $("#againMetting")[0].style.display = "inline";//显示 $("#againMettin ...

  10. JVisualVM监控本地Java进程

    一.基于JVisualVM的可视化监控 1.打开C:\Program Files\Java\jdk1.8.0_131\bin下的jvisualvm.exe 2.打开后,会列出本机所有的Java进程 3 ...