天天看点

(8)虚函数测试

#include <iostream>

using namespace std;


void TestVirtualFunction();

void TestVirtualClass();

void TestDrivedClass();

void TestDefaultParam();

/*
	1.如果调用非虚函数,则无论实际对象是什么类型,都执行基类类型所定义的函数
	2.如果调用虚函数,则直到运行时才能确定调用哪个函数,
	运行的虚函数是引用所绑定的或指针所指向的对象所属类型定义的版本。
	3.当程序中函数是非虚函数调用时,B类对象对函数p()的调用时在编译时就已静态确定

	4.虚函数是动态绑定,而缺省参数是静态绑定的
*/
class A
{
public:
	virtual void p()
	{
		cout << "A" << endl;
	}
};

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

class Base
{
private: 
	virtual void p()
	{
		cout << "Base::p()" << endl;
	}
};

class Drived : public Base
{
};

class BD 
{ 
public: 
	virtual void fun(int i = 1) 
	{ 
		std::cout << "base fun called, " << i; 
	}; 
}; 
class D : public BD 
{ 
private: 
	virtual void fun(int i = 2) 
	{ 
		std::cout << "driver fun called, " << i; 
	}; 
};
           
#include <iomanip>

#include "8_VirtualFunction.h"


void TestVirtualFunction()
{
	//TestVirtualClass();
	//TestDrivedClass();

	TestDefaultParam();
}

void TestVirtualClass()
{
	A *pA = new A();
	A *pB = new B();
	pA->p();
	pB->p();

	delete pA;
	delete pB;
}

void TestDrivedClass()
{
	typedef void (*Fun)(void);
	Drived d;
	Fun pFun = (Fun)*(((int *)(&d)) + 0);
	cout << hex << setw(8) << &d << endl;
	// 对象地址
	cout << hex << setw(8) << (int *)(&d) << endl;
	// 对象的前四个字节的值(虚函数表的地址)
	cout << hex << setw(8) << *(int *)(&d) << endl;
	// 虚函数表第一项的地址
	cout << hex << setw(8) << (int *)*(int *)(&d) << endl;
	// 虚函数表第一项的地址
	cout << hex << setw(8) << (int *)*(int *)(&d) + 0 << endl;
	// 虚函数表第一项的内容
	cout << hex << setw(8) << *((int *)*(int *)(&d) + 0) << endl;
	cout << hex << setw(8) << (Fun)*((int *)*(int *)(&d) + 0) << endl;

	Fun pFun2 = (Fun)*((int*)*(int*)(&d)+0);
	pFun2();
}

void TestDefaultParam()
{
	BD *pD = new D();
	pD->fun();

	delete pD;
}
           

继续阅读