我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数。这种调用都是对象已经构建完成的情况。那如果在构造函数中调用虚函数,会怎么样呢?

有这么一段代码:

class A
{
public:
A ():m_iVal(){test();}
virtual void func() { std::cout<<m_iVal<<‘ ’;}
void test(){func();}
public:
int m_iVal;
};
class B : public A
{
public:
B(){test();};
virtual void func()
{
++m_iVal;
std::cout<<m_iVal<<‘ ’;
}
};
int main(int argc ,char* argv[])
{
A*p = new B;
p->test();
return ;
}

  输出: 0 1 2

  也就是说,在构造函数中调用虚函数,调用的是正在构造的类中的虚函数,而不是子类的虚函数。

  理一下程序。new了一个B对象,首先要调用基类构造函数,也就是A类的构造函数。调用test(),再调用虚函数func(),这时候用的是基类版本。之后再调用子类B的构造函数,这时调用的是子类虚函数func()。至于最后一次调用func(),根据多态,调用的是真实虚函数。

C++ 构造函数中调用虚函数的更多相关文章

  1. 关于在C#中构造函数中调用虚函数的问题

    在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...

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

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

  3. C++中构造函数能调用虚函数吗?(答案是语法可以,输出错误),但Java里居然可以

    环境:XPSP3 VS2005 今天黑总给应聘者出了一个在C++的构造函数中调用虚函数的问题,具体的题目要比标题复杂,大体情况可以看如下的代码: class Base { public: Base() ...

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

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

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

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

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

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

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

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

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

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

  9. C# 构造函数中调用虚方法的问题

    请看下面代码: using System; public class A{ public A(){ M1(); } public virtual void M1(){} } public class ...

随机推荐

  1. Nginx: could not build the server_names_hash 解决办法

    # /etc/init.d/nginx reload * Reloading nginx configuration nginx [fail] # nginx -t nginx: [emerg] co ...

  2. 【转载】取消Debian系统自动锁屏

    Linux的自动锁屏功能,会在你离开屏幕的两分钟,甚至更短的时候内,将屏幕锁住,需要输入密码才能进入Linux系统. 可按下图设置,关掉Linux自动锁屏功能 System-->Preferen ...

  3. JAVA jdbc(数据库连接池)学习笔记(二) SQL注入

    PS:今天偶然间发现了SQL的注入...所以就简单的脑补了一下,都是一些简单的例子...这篇写的不怎么样...由于自己没有进行很深的研究... 学习内容: 1.SQL注入的概念...   所谓SQL注 ...

  4. jquery判断radioButton是否被选中

    so easy HTML: <input type='radio' style='width:20px' id='other' name='projectType' value='其他' /&g ...

  5. CentOS6.5菜鸟之旅:安装VirtualBox4.3

    一.下载VirtualBox的RHEL软件库配置文件 cd /etc/yum.repos.d wget http://download.virtualbox.org/virtualbox/rpm/rh ...

  6. http与websocket(基于SignalR)两种协议下的跨域基于ASP.NET MVC--竹子整理

    这段时间,项目涉及到移动端,这就不可避免的涉及到了跨域的问题.这是本人第一次接触跨域,有些地方的配置是有点麻烦,导致一开始的不顺. 至于websocket具体是什么意义,用途如何:请百度. 简单说就是 ...

  7. WatiN和HttpWatch交互简介

    Httpwatch是一款强大的网页数据分析工具,它可以在不改变浏览器和网络设置的基础上捕捉http和https数据.查看底层的http数据,包括headers, cookies, cache等,同时统 ...

  8. 1 初识Orchard

    网上关于Orchard的介绍已经很多了,具体Orchard是干啥的我就不再啰嗦,这个系列的主要目的就是介绍学习和使用orchard的过程,和在此过程中碰到问题的解决方案.下面直接进入正题. 获取orc ...

  9. sql apply

    可以给表值函数传column,而join不可以

  10. Install gocode

    1. D:\AWS_workspace\DAAS_Go>go get -u -ldflags -H=windowsgui github.com/nsf/gocode 2. Then gocode ...