C++的虚函数及虚指针

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

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; //没有虚函数类的对象
}

由上图可以看出,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;
}

由上图可以看出,基类的对象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;  //派生类创建多个对象
}

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

对于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;
}

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

对于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;
}

看,多重继承了吧?

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

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

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

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页