码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-03-02 14:54:23      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:

谈谈关于构造函数中调用虚函数的情况,仅讨论单继承,不考虑虚拟继承和多重继承。
测试平台: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: 003FDC78
Deri: 0028F980  VTable: 003FDC98

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



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

标签:

原文地址:http://blog.csdn.net/alex_my/article/details/44017509

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!