欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++的虚函数及虚指针

程序员文章站 2024-03-17 08:09:58
...

首先,本文的绝大部分思路来自于该博客,向博主表示感谢

https://blog.twofei.com/496/

先看上述文章,再看本文,估计收获更大

结论

总的来说:
1.虚函数表是针对“”而言:

(1)当该类有虚函数时,就会生成虚函数表(一个存放虚函数指针函数指针数组),一个虚函数表对应一个虚指针;

(2)当该类作为基类,其派生类对基类的(一个或者多个)虚函数进行重写时,派生类的虚函数表中,相应的函数指针的值就会发生变化;

2.虚指针是通过“类的对象”来体现:

(1)同一个类,创造的不同对象,其虚指针的值是一样的,全都是指向该类的虚函数表(函数指针数组的首地址?应该是了);
(2)不同的类创建的对象,无论其基类的虚函数是否被重写,其虚指针的值(与其基类创建的对象相比)是不同的;

3.对于多重继承:

经过多重继承的派生类,其含有多个虚指针(肯定啊!毕竟虚函数表是和类有直接关系的,派生类继承于多个基类,当然有多个虚函数表啦~~~也就有多个虚函数指针啦~~~),且派生类对象虚和基类对象的虚指针的值不同,无论是否进行虚函数的重写(当然啦!毕竟是不同的类生成的对象嘛~~~而且进行虚函数的重写,影响的是虚指针,这个函数指针数组中,元素的值,注意断句啊亲)。

理解了上述两大点,这第三大点也就顺理成章的理解了

下面,有图有真相,biu~biu~biu~

环境:win7+VS2012

对于1.1的解释:当该类有虚函数时,就会生成虚函数表(一个存放虚函数指针函数指针数组

class Base1  //有虚函数
{
public:
	virtual void f1()
	{
		cout<<"Base1 vir_f1"<<endl;
	}
	virtual void f2()
	{
		cout<<"Base1 vir_f2"<<endl;
	}
};
class Base2  //没有虚函数
{
	void f3()
	{
		cout<<"Base2 vir_f3"<<endl;
	}
	void f4()
	{
		cout<<"Base2 vir_f4"<<endl;
	}
};
int main()
{
	Base1 b1; //有虚函数类的对象
	Base2 b2; //没有虚函数类的对象
}

C++的虚函数及虚指针

由上图可以看出,Base1类是有虚函数的,其创建的对象,有虚函数表(红色部分的下面,[0][1]分别是虚函数的函数指针);而Base2类是没有虚函数的,其创建的对象,没有虚函数表

对于1.2的解释:当该类作为基类,其派生类对基类的(一个或者多个)虚函数进行重写时,派生类的虚函数表中,相应的函数指针的值就会发生变化

class Base1  //基类,带2个虚函数
{
public:
	virtual void f1()
	{
		cout<<"Base1 vir_f1"<<endl;
	}
	virtual void f2()
	{
		cout<<"Base1 vir_f2"<<endl;
	}
};

class Deriver:public Base1  //派生类,仅重写一个基类的虚函数
{
public:
	virtual void f1()
	{
		cout<<"Deriver vir_f1"<<endl;
	}
};
int main()
{
	Base1 b1;
	Deriver d1;
}

C++的虚函数及虚指针

由上图可以看出,基类的对象b1,派生类的对象是d1,其中,b1和d1中的第一个元素[0]的值不同,是因为派生类已经对基类的虚函数f1()进行了重写,而b1和d1中的第二个元素[1]值相同,是因为派生类没有对虚函数f2()进行重写

对于2.1的解释:同一个类,创造的不同对象,其虚指针的值是一样的,全都是指向该类的虚函数表

class Base1
{
public:
	virtual void f1()
	{
		cout<<"Base1 vir_f1"<<endl;
	}
	virtual void f2()
	{
		cout<<"Base1 vir_f2"<<endl;
	}
};

class Deriver:public Base1  //派生类重写虚函数
{
public:
	virtual void f1()
	{
		cout<<"Deriver vir_f1"<<endl;
	}
    virtual void f2()
    {
        cout<<"Deriver vir_f2"<<endl;
    }
};

int main()
{
	Base1 b1,b2,b3;  //基类创建多个对象
	Deriver d1,d2,d3;  //派生类创建多个对象
}

C++的虚函数及虚指针

看,同一类,创建的所有对象,其虚函数指针的值都是相同的

对于2.2的解释:不同的类创建的对象,无论其基类的虚函数是否被重写,其虚指针的值(与其基类创建的对象相比)是不同的

(将基类的虚函数进行重写,在1.2中已完成,不再进行说明,下述派生类没有重写基类的虚函数的情况)

class Base1
{
public:
	virtual void f1()
	{
		cout<<"Base1 vir_f1"<<endl;
	}
	virtual void f2()
	{
		cout<<"Base1 vir_f2"<<endl;
	}
};

class Deriver:public Base1  //派生类没有重写虚函数
{};

int main()
{
	Base1 b1;
	Deriver d1;
}

C++的虚函数及虚指针

看,派生类并没有对基类的虚函数进行重写,但派生类对象和基类对象的虚函数指针是不同滴~~~~

对于3的解释:

class Base1   //基类1
{
public:
	virtual void f1()
	{
		cout<<"Base1 vir_f1"<<endl;
	}
	virtual void f2()
	{
		cout<<"Base1 vir_f2"<<endl;
	}
};

class Base2   //基类2
{
	virtual void f3()
	{
		cout<<"Base2 vir_f3"<<endl;
	}
	virtual void f4()
	{
		cout<<"Base2 vir_f4"<<endl;
	}
};

class Deriver:public Base1,public Base2  //多重继承,并且把基类全部的虚函数进行了重写
{
	virtual void f1()
	{
		cout<<"Deriver vir_f1"<<endl;
	}
	virtual void f2()
	{
		cout<<"Deriver vir_f2"<<endl;
	}
	virtual void f3()
	{
		cout<<"Deriver vir_f3"<<endl;
	}
	virtual void f4()
	{
		cout<<"Deriver vir_f4"<<endl;
	}
};

int main()
{
	Base1 b1;
	Base2 b2;
	Deriver d1;
}

C++的虚函数及虚指针

看,多重继承了吧?

派生类的有两个虚指针吧?(因为派生类继承于两个基类啊)

这两个虚指针的值和基类对象的虚指针值不一样吧?(因为派生类和两个基类,分属于三个不同的类啊)

派生类中,虚指针中元素的值     和对应基类的    虚指针中   元素的值    不一样吧?(因为派生类把所有的虚函数进行了重写了啊,否则对应元素的值是相同的,毕竟指向的是同一个函数啊)

相关标签: 虚函数 虚指针

上一篇: 最短路

下一篇: 最短路