C++构造函数中调用虚函数

谈谈关于构造函数中调用虚函数的情况,仅讨论单继承,不考虑虚拟继承和多重继承。

测试平台:VS2013 + Win7X64

一个例子:

#include <stdlib.h>#include <stdio.h>class Base{private: int __data;public: Base() { this->Func(); }public: virtual void Func() { printf("Base::Func"); }};class Deri : public Base{public: Deri() {

this->Func(); }public: virtual void Func() { printf("Deri::Func\n"); }};int main(int argc, char** argv){ Deri d; getchar(); return 0;}

输出:

Base::Func

Deri::Func

首先讨论下对象d的构造情况。

1 先构造基类部分,,调用基类Base的构造函数,这个时候,派生类部分还没有产生,这时候虚表应该是绑定基类的,自然调用的是Base::Func()

2 再构造派生类部分,这个时候,虚表发生变化,绑定在派生类上,调用Deri::Func()

虽然,在派生类中有重载Func这个函数,但是,在构造基类部分的时候,派生类的成员数据还没有初始化,如果是调用派生类中的Func,会造成错误,内存越界甚至崩溃。

在函数中,可以通过打印虚表地址:

— Base::Func()

int* vtl = (int*)*((int*)this);

std::cout << "Base: " << this << " VTable: " << vtl << std::endl;

— Deri::Func()

int* vtl = (int*)*((int*)this);

std::cout << "Deri: " << this << " VTable: " << vtl << std::endl;

输出:

Base: 0028F980 VTable: 003FDC78Deri: 0028F980 VTable: 003FDC98

发现,虚表的地址是不断变化的。

不畏不惧,不言不弃,冲破风雨的阻隔,黎明就在前方!

C++构造函数中调用虚函数

相关文章:

你感兴趣的文章:

标签云: