简 述: 对于 C++ 中的多次继承后,其中含有虚函数的时候,探究一下其中的虚函数表;以及其变量在内存中的分布情况。

[TOC]


本文初发于 “偕臧的小站“,同步转载于此。


编程环境:

  💻: Win10 2004 📎 VS2015 x86模式


虚函数表验证:

对于任意的一个类,若是其中有虚函数 virtual 的话,就会有一个虚函数指针,负责其自己的虚函数表。代码就是最好的讲解,上代码:

// vtableptr.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
using namespace std;

class A {
public:
	virtual void vfunc1() { cout << "A::vfunc1()" << endl; }
	virtual void vfunc2() { cout << "A::vfunc2()" << endl; }
	void func1() { cout << "A::func1()" << endl; }
	void func2() { cout << "A::func2()" << endl; }

	//private:
	int m_data1 = 11;
	int m_data2 = 12;
};

class B : public A {
public:
	virtual void vfunc1() { cout << "B::vfunc1()" << endl; }
	void func2() { cout << "B::func2()" << endl; }

	//private:
	int m_data3 = 13;
};

class C : public B {
public:
	virtual void vfunc1() { cout << "C::vfunc1()" << endl; }
	void func2() { cout << "C::func2()" << endl; }

	//private:
	int m_data4 = 14;
};

int main(void)
{
	A a;
	B b;
	C c;

	a.func1();
	a.func2();

	b.func1();
	b.func2();

	c.func1();
	c.func2();

	cout << sizeof(A) << "   " << sizeof(B) << "    " << sizeof(C) << endl;
	return 0;
}

然后运行如下:

查看一下内存地址分析:

将其用表格图形化分析一波,可以看到,对于重写的基类的虚函数的派生类,其维护的虚函数表,就是基类未被重写的虚函数地址加上自己的(已经重写)虚函数。


类中成员的空间位置:

在来一个类,由下图份的内存位置分析可知,静态成员和静态变量、以及成员函数也是是单独放在其它地方的

class CTest
{
    public:
        CTest():m_chData(‘\0),m_nData(0)
        {
        }
        virtual void mem_fun(){}
    private:
        char m_chData;
        int m_nData;
        static char s_chData;
};
char CTest::s_chData=’\0;


通过上面来两个例子,我觉着已经很清晰了,不再需要怎么说。而关于一个程序在内存中的布局,可以参考之前的一片文章 运行程序所分配的地址空间