C++子类在成员函数中不要转型为父类

本文深入探讨了C++中基类和派生类之间通过模板转型进行函数调用的机制,指出转型可能导致函数调用的对象不是当前对象本身,而是对象的基类部分的临时副本。并通过实例代码解释了这种现象,并引用了《Effective C++》一书中的条款27来强调减少转型操作的重要性。

        请看以下代码,我们有个Base和一个Derived类,它们都定义了virtual函数test,然后Derived的test调用了Base的test,下面是实现方式之一,它看起来是对的,但实际上是错的。

#include <iostream>
using namespace std;

class Base
{
public:
	virtual void test()
	{
		cout << "Base::test() " << b << endl;
		b = 1;
		cout << "Base::test() " << b << endl;
	}

protected:
	int b;
};

class Derived : public Base
{
public:
	virtual void test()
	{
		/*
		 * 将*this转型为Base,然后调用test,这种方式并非在当前对象身上调用Base::test()之后又在
		 * 该对象身上执行Derived的专属动作。而是在当前对象base class成分的副本上调用Base::test,
		 * 然后在当前对象身上执行Derived的专属动作。如果Base::test()对数据成员有更改,实际上更改的
		 * 是其副本,对该Derived对象没有影响。
		 */
		static_cast<Base>(*this).test();

		// 这种方式才是调用Base::test作用于*this本身
		//Base::test();

		cout << "Derived::test() " << b << endl;
		b = 2;
		cout << "Derived::test() " << b << endl;
	}
};

int main(void)
{
	Derived d;

	d.test();

	system("pause");
	return 0;
}


        这段程序将*this转型为Base,对函数test的调用也因此调用了Base::test,但是它调用的并不是当前对象上的函数,而是稍早转型动作所建立的一个"*this对象之base class成分"的暂时副本上的test。


参考资料:

        《Effective C++》 条款27 尽量少作转型动作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值