C++学习笔记:类的类型转换

C++ Primer第五版P535页有这样一段话:在对象之间不存在类型转换。派生类向向基类的自动类型转换只对指针或引用类型有效,在派生类类型和基类类型之间不存在这种转换。

#include<iostream>
#include<stdlib.h>
#include<typeinfo.h>
using namespace std;
class animal
{
public:
	void eat()
	{
		cout<<"animal eat"<<endl;
	}
	void sleep()
	{
		cout<<"animal sleep"<<endl;
	}
	 void breath()
	{
		cout<<"animal breath"<<endl;
	}
};
class fish:public animal
{
public:
	void breath()
	{

		cout<<"fish breath"<<endl;
	}
};

void fn(animal species)
{
	species.breath();
	cout<<typeid(species).name()<<endl;
}
void main()
{
	fish fh;
	//fish* fit;
	//fit=&fh;
	//fn(fit);
	fn(fh);
	//cout<<typeid(fit).name()<<endl;
	cout<<typeid(fh).name()<<endl;
	//cout<<typeid(fh).name()<<endl;
	system("pause");
}

在这里,调用fn实参传入时,fish难道不是向animal进行了隐式转换吗?
现在大体知道以上程序通过编译的原因是发生了切掉(sliced down)。
也就是说,当我们用一个派生类对象为一个基类对象初始化赋值时,只有该派生类中的基类部分会被拷贝、移动或赋值,它的派生类部分将被忽略掉。

其实,这和使用指针是相似的。看了半天,我理解的是这样:利用指针进行从派生类到基类的类型转换时,该指针仍是只能指向派生类对象中的基类部分,从狭义功能上来讲,其与类类型转换无差异。
比如

#include<iostream>
#include<stdlib.h>
#include<typeinfo.h>
using namespace std;
class animal
{
public:
	void eat()
	{
		cout<<"animal eat"<<endl;
	}
	void sleep()
	{
		cout<<"animal sleep"<<endl;
	}
	virtual void breathe()
	{
		cout<<"animal breathe"<<endl;
	}
};
class fish:public animal
{
public:
	void breathe()
	{

		cout<<"fish breathe"<<endl;
	}
	void test()
	{
		cout<<"test用来判断,将基类的指针或引用绑定到派生类对象时,是否可以利用该指指针或引用调用派生类中的成员"<<endl;
	}
};

void fn(animal* species)
{
	//species->fish::breathe();		//非法,提示animal中无breathe,尽管我们定义了虚函数
	//species->fish::test();						//非法
	species->breathe();							//这种调用方式最终调用了fish中的虚函数
	species->animal::breathe();
	cout<<typeid(species).name()<<endl;
}
void main()
{
	fish fh;
	animal* fit;
	fit=&fh;
	fn(fit);
	//fn(fh);
	cout<<typeid(fit).name()<<endl;
	cout<<typeid(fh).name()<<endl;
	//cout<<typeid(fh).name()<<endl;
	system("pause");
}

那么,使用指针的好处就是可以实现多态了。这才是根本区别。也就是说,若进行了类类型转换,animal就是animal了,编译器是不去记录它原来是什么类型的,也就不存在多态这个说法了。而使用指针时,并在基类中定义虚函数,那么就会触发动态绑定(dynamic binding),运行时就会根据对象的实际类型来调用相应的函数,实现了多态(Polymorphism)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值