//############################################################################
/*
任何时候都不要在构造函数或析构函数中调用虚函数
*/
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. Java中的Arrays类使用详解

    首先先创建一个打印数组的方法,方便后面直接使用 public static void output(int []a) { for(int i=0;i<a.length;i++) { System ...

  2. SEO:网站优化内容

    一.内部优化 (1)meta标签优化:例如:TDK等的优化:        首页:网站名称 或者 网站名称_提供服务介绍or产品介绍 .        频道页:频道名称_网站名称.        文章 ...

  3. xdoj新生现场赛1269——带有限制条件的bfs 寻找最短路径

    bfss是解决最短路径的强大武器 (尝试dfs寻找最短路径 -(7*7)就会爆炸) 例题1  ccf 201604-4  游戏 问题描述 小明在玩一个电脑游戏,游戏在一个n×m的方格图上进行,小明控制 ...

  4. java-接口的概述及其特点

    1.接口概述: - 从狭义的角度讲就是指java中的interface - 从广义的角度讲对外提供规则的都是接口 2.接口特点: - 接口中定义的全都是抽象方法. - 接口用关键字interface表 ...

  5. PHP学习-类

    类属性: 在类的成员方法里面,可以用 ->(对象运算符):$this->property(其中 property 是该属性名)这种方式来访问非静态属性.静态属性则是用 ::(双冒号):se ...

  6. Maven命令安装jar包到本地仓库

    https://blog.csdn.net/moxiong3212/article/details/78767480 当需要的jar包在中央仓库找不到或者是想把自己生成的jar包放到的Maven仓库中 ...

  7. golang-build-error

    工程中同时有两个main文件,编译的时候提示: go build proxy/proxy.go pb/anti_spam.pb.go::: cannot find package "_/Us ...

  8. day2 python学习

    1.格式化输出 现有一练习需求,问用户的姓名.年龄.工作.爱好 ,然后打印成以下格式 复制代码 ------------ info of Alex Li ----------- Name : Alex ...

  9. src-d engine 强大的git 历史分析工具

    src-d engine 包含了Babelfish ,同时可以看作是Babelfish 的升级版本,我们可以使用sql 进行代码分析 备注: 注意运行的时候需要容器支持 使用 安装docker   参 ...

  10. c# 数据类型可在在最后的带一个字母

    folat的后面要带F或者f: double的后面要带D或者d: decimal的后面要带M或者m: long的后面要带L或者l: