数据类型转换和运算符重载
一、数据类型转化(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的前缀。

浙公网安备 33010602011771号