C++类相关总结-1

1. 虚函数的实现原理 ios

    在C++的类内会维护一个虚表,同时还有一个虚指针。能够经过VC 6.0来观看类的虚函数表。 网络

#include <iostream>
#include <stdio.h>

class A{
public :
	virtual void f(){ std::cout<<"This is A's f"<<std::endl;};
	virtual void g(){ std::cout<<"This is A's g"<<std::endl;};
};

class B : public A{
public:
	B(){};
	void f(){ std::cout<<"This is B's f"<<std::endl;};
};

class C : public A{
public:
	void g(){ std::cout<<"This is C's g"<<std::endl;};
};

class D : public C,B{
public:
	void f(){ std::cout<<"This is D's f"<<std::endl;};
	void g(){ std::cout<<"This is D's g"<<std::endl;};
};

#define E_ss E::ss()

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

	std::cout<<"A's address is "<<&a<<std::endl;
	std::cout<<"B's address is "<<&b<<std::endl;
	std::cout<<"C's address is "<<&c<<std::endl;
	std::cout<<"D's address is "<<&d<<std::endl;

	return 0;
}

    

    C++的类中第一个变量就是虚指针。其中a类的地址是0x0012ff44,紧接着就是虚指针。而b类的地址为0x0012ff40,因而可知a类内只有虚指针这一个变量。 函数

    

    解决了虚指针的问题,如今正式进入虚函数表。从代码能够看到,A类内定义了两个虚函数 f() 和 g() ,B类继承A类,实现了虚函数 f() ,并无实现 g() , C类正好相反。D类暂时不讨论,她负责解释多重继承产生二义性的问题。 spa

    经过VC 6.0的调试能够看到各个虚函数的地址,如图。 指针

    

    能够看到,a类的虚指针里有两个虚函数地址分别为0x004012cd(A::f(void))和0x004011b8(A::g(void))。而b类继承a类,因为b类只实现了虚函数f(),因此b类的虚指针内的B::f(void)是指向b类内实现的虚函数,而g()函数仍是指向A类的A::g(void)函数。C类则与B类相似。 调试

    总结下,C++的类是经过一个虚指针(__vfptr)指向一个虚函数表来实现虚函数的功能,从而实现动态的多态。 code

2. 经过子类调用父类”们“方法 继承

    依然是刚才那段代码,我在B、C、D类内分别写了test(),来调用父类”们“的方法。 io

#include <iostream>
#include <stdio.h>

class A{
public :
	virtual void f(){ std::cout<<"This is A's f"<<std::endl;};
	virtual void g(){ std::cout<<"This is A's g"<<std::endl;};
};

class B : virtual public A{
public:
	void f(){ std::cout<<"This is B's f"<<std::endl;};
	void test()
	{
		std::cout<<"This is B's test"<<std::endl;
		A::f();
		A::g();
	}
};

class C : virtual public A{
public:
	void g(){ std::cout<<"This is C's g"<<std::endl;};
	void test()
	{
		std::cout<<"This is C's test"<<std::endl;
		A::f();
		A::g();
	}
};

class D : public C,B{
public:
	void f(){ std::cout<<"This is D's f"<<std::endl;};
	void g(){ std::cout<<"This is D's g"<<std::endl;};
	void test()
	{
		std::cout<<"This is D's test"<<std::endl;
		A::f();
		A::g();
		B::f();
		C::g();
	}
};

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

	b.test();
	c.test();
	d.test();

	return 0;
}

    

    在运行时对继承方式作了修改,经过网络图和结果显示。具体请看下图。 class

            

            

            

    总结下,无论怎么继承子类均可以调用父类的方法,可是当子类B、C私有继承类A时,类B、C的子类D则不能调用类A的方法。

相关文章
相关标签/搜索