虚函数的静态解析

文章讨论了C++中虚函数在基类构造函数和析构函数内部以及使用基类对象而非指针或引用时可能出现的非预期行为。在构造和析构过程中,由于对象状态,调用的总是当前类的虚函数。当以基类对象传递派生类时,派生类的额外数据成员会被切除,导致调用的虚函数是基类的,而非派生类的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一.基类的constructor和destructor内

二.使用的是基类的对象而不是基类对象的pointer或reference


存在两种情况,虚函数机制不会出现预期行为:

  即不根据虚函数的机制来调用类中对应的虚函数

示例中使用的基类和派生类:

class base_class
{
private:
	string base_logo;
public:
	virtual void print()const
	{
		cout << "base_class" << endl;
	}
	base_class(string logo) 
	{
		base_logo = logo;
		print();
	}
	~base_class()
	{
		print();
	}
};

class derived_class:base_class
{
private:
	string derived_logo;
public:
	virtual void print()const
	{
		cout << "derived_logo" << endl;
	}
	derived_class(string logo)
	{
		derived_logo = logo;
		print();
	}
	~derived_class()
	{
		print();
	}
};

示例中使用的函数:

void print(base_class d1, base_class* d2, base_class& d3) //基类引用和指针为参数类型时,可以传递基类或派生类作为参数
{
	d1.print();

	d2->print();

	d3.print();
}

一.基类的constructor和destructor内

1.原理:在构造派生类对象时,基类的构造函数先被调用,且此时派生类中的data member尚未初始化,若此时基类构造函数调用派生类的那一份虚函数,则可能访问未经初始化的data member,因此在构造函数中只会调用该类本身的虚函数。(对于析构函数destructor原理一致)

2.演示示例:

int main()
{
	//基类对象
	base_class b1("base");
	b1.~base_class();

	//派生类对象
	derived_class d1("derived");
	d1.~derived_class();

	system("pause");
	return 0;
}

如运行结果所示:基类,派生类各自的构造函数和析构函数中调用的虚函数均是自己类中的虚函数。

二.使用的是基类的对象而不是基类对象的pointer或reference

1.原理:当我们为基类声明了一个实际对象,同时也就分配出了足够容纳该实际对象的内存空间,如果稍后传入的是派生类对象,则没有足够的内容放置派生类中的各个data member。(因此,若将派生类参数传给基类参数类型,则会将派生类多出的部分切除)

2.演示示例:

int main()
{
	//基类对象
	base_class b1("base");

	//派生类对象
	derived_class d1("derived");
	
	print(d1, &d1, d1);
	
	system("pause");
	return 0;
}

函数的第一个参数是一个实际对象,而第二个第三个参数分别是指针和引用。

如运行结果所示:第一个参数对象调用的print()中调用的虚函数为基类的虚函数,第二个第三个参数对象调用的print()中调用的虚函数为派生类的虚函数。(因此将类对象作为参数传递时,最好均以指针或是引用的方式进行传递)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值