数据类型转换和运算符重载

一、数据类型转化(data type conversion)

  目的对象中的例程 源对象中的例程
基本类型—>基本类型 内置的转换运算符  
基本类型—>用户自定义类型 构造函数 N/A
用户自定义类型—>基本类型 N/A 转换运算符
用户自定义—>用户自定义 构造函数 转换运算符

 

下面我们通过具体的实例来理解上表的含义:

1.用户自定义<—>基本类型

#include <iostream>
using namespace std;
//////////////////////////////////////////////////////////////////////////
class Distance
{
private:
	const float MTF;
	int feet;
	float inches;
public:
	Distance():feet(0),inches(0.0),MTF(3.28F) {}
	Distance(float meters):MTF(3.28F)
	{
		float fi=meters*MTF;
		feet=int(fi);
		inches=12*(fi-feet);
	}
	Distance(int ft,float in):feet(ft),inches(in),MTF(3.28F) {}
	void getdist()
	{
		cout<<"Enter the feet:";cin>>feet;
		cout<<"Enter the inches:"; cin>>inches;
	}
	void showdist()
	{
		cout<<feet<<"\'"<<"-"<<inches<<"\""<<endl;
	}
	operator float () const
	{
		float ff=inches/12;
		ff+=static_cast<float>(feet);
		return ff/MTF;
	}
};
//////////////////////////////////////////////////////////////////////////
int main()
{
	float meter;
	Distance dist1=2.35F;  //uses 1-arg constructor to
	                       //convert meters to Distance
	cout<<"dist1= ";dist1.showdist();
	meter=static_cast<float>(dist1); //uses conversion operator(explicit)
	                                 //for Distance to meters
	cout<<"dist1= "<<meter<<" meters"<<endl;
	Distance dist2(5,10.25);
	meter=dist2;        //also uses conversion op(implicit)
	cout<<"dist2= "<<meter<<" meters"<<endl;
	//dist2=meter;   //**error: = won't convert
	               //    
	return 0;
}

 

从上面我们可以看出:基本类型—>用户自定义 用单参数的构造函数(转换构造函数conversion constructor)

                                      用户自定义—>基本类型 用转换运算符(conversion operator)

2.c字符串与String对象之间的转换

#include <iostream>
#include <string.h>
using namespace std;
////////////////////////////////////////////////////////////////////////
class String 
{
private:
	static const int SZ=80;
	char str[SZ];
public:
	String()
	{
		str[0]='\0';    
		strcpy(str,"");
	}
	String(char s[])
	{
		strcpy(str,s);
	}
	void display() const
	{
		cout<<str;
	}
	operator char* ()
	{
		return str;
	}
};
////////////////////////////////////////////////////////////////////////
int main()
{
	String s1;
	char xstr[]="nihao,haha!";
	s1=xstr;   //为什么这里又能够转换了
	s1.display();
	String s2="Bonne Annee!";
	cout<<static_cast<char*>(s2); //use conversion operator(explicit)
	cout<<endl;
	return 0;
}

 

1)上面注释:为什么这里能转换,对比的是上一个程序中的dist2=meter; 两者都是从基本类型转化为用户自定义类型,但是为什么一个可以一个不可以呢?

答:

2)第二句注释的地方告诉我们:转换不仅发生在赋值语句中,在其他适合的场合也会发生,如传递给运算法(如<<)或者函数的参数中。

3)在这里如果有一句:xstr=s2;(把用户自定义类型—>基本类型)对不对呢?

答案是不行的,因为c字符串是一个数组,s2为了传给xstr会首先调用转换运算符 char*,但是他返回的是 一个数组的首地址,在这里我们会想到数组是不能以通常的方式(=)给另一个数组赋值的。

二、关键字explicit和mutable

1.explicit是用来防止转换的

阻止转换运算符的执行的转换比较容易:不定义运算符就可以了。不过如果牵扯到构造函数,事情就不那么简单了。

例子:

/************************************************************************/
/* explicit.cpp
/************************************************************************/
#include <iostream>
using namespace std;
class Distance
{
private:
	const float MTF;
	int feet;
	float inches;
public:
	Distance():feet(0),inches(0.0),MTF(3.28F) {}
	explicit Distance(float meters):MTF(3.28F)
	{
		float fi=meters*MTF;
		feet=int(fi);
		inches=12*(fi-feet);
	}
	void getdist()
	{
		cout<<"Enter the feet:";cin>>feet;
		cout<<"Enter the inches:"; cin>>inches;
	}
	void showdist()
	{
		cout<<"the distance is:"<<feet<<"\'"<<inches<<"\"";
	}
};
void functiond(Distance dd)
{
	dd.showdist();
}
int main()
{
	float meters=2.0F;
	Distance d1;
	Distance d2(2.3F);
	//Distance d3=2.3F;
	//functiond(meters);
	return 0;
}

显示构造函数的副作用就是,不能使用带有等号的对象初始化形式。 在函数调用的时候,也牵扯到一个从meters到dd转化过程,而此过程是隐式的所以编译器也会报错。2)使用mutable可以改变const对象的数据

/************************************************************************/
/* multab.cpp
/************************************************************************/
#include <iostream>
using namespace std;
class scrollbar
{
public:
	scrollbar(int si,string own):size(si),owner(own) {}
	void setsize(int siz) const
	{
		size=siz;
	}
	void setowner(string str) /*const*/
	{
		owner=str;
	}
	int getsize() const
	{
		return size;
	}
	string getowner() const
	{
		return owner;
	}
private:
	/*mutable */int size;
	mutable string owner;
};
int main()
{
	const scrollbar ss(122,"windows");
	ss.setsize(100);    //错误,const对象只能调用const成员函数,因为没有mutable不能修改
	ss.setowner("linux"); //错误,const对象只能调用const成员函数,即便owner前有mutable。
	ss.getowner();
	ss.getsize();
	return 0;
}

因此我们要向改变const对象的数据必须具备两个条件:首先,const对象的成员函数是const类型的;其次,定义的数据成员必须要有mutable的前缀。

 
posted @ 2011-09-11 15:43  csqlwy  阅读(1496)  评论(0编辑  收藏  举报