C++重载类型转换操作符
2016-02-06 15:13
411 查看
原文链接 http://blog.csdn.net/yby4769250/article/details/7332449
在需要做数据类型转换时,一般显式的写法是:
[cpp] view
plain copy
<span style="font-size:18px;">type1 i;
type2 d;
i = (type1)d; //显式的写类型转,把d从type2类型转为type1类型</span>
这种写法不能做到无缝转换,也就是直接写 i = d,而不需要显式的写(type1)来向编译器表明类型转换,要做到这点就需要介绍一下“类型转换操作符”,拿最简单的基本类型封包解包来举例:
[cpp] view
plain copy
class Integer
{
public:
Integer(int v);
Integer& opetaror =(const int &v); //重载赋值操作符,可以做到 Integer i = 10;//把i当基本数据类型使用
operator int(); //重载类型转换操作符,可以做到int i; Integer it; i = it; //it直接转为int类型,然后赋值给i
private:
int data;
};
Integer::Integer(int v)
{
data = v;
}
/*!
*@brief 重载赋值操作符,可以做到 Integer i = 10;//把i当基本数据类型使用
*/
Integer& Integer::opetaror =(const int &v)
{
data = v;
return *this;
}
/*!
*@brief 重载类型转换操作符,可以做到int i; Integer it; i = it; //it直接转为int类型,然后赋值给i
*/
Integer::operator int()
{
return data;
}
#include <iostream>
using namespace std;
int main()
{
Integer integer1(10); //调用构造函数进行初始化
Integer integer2;
int i1 = 10;
integer2 = i1; //调用=赋值操作符进行赋值
//下面测试类型转换操作符的应用
int i2;
i2 = integer1; //integer1是Integer类型,这里直接把Integer类型转换为int,然后赋值给i2
//如果没有重载了int(),需要类型转换的话,这里必须写成 i2 = (int)integer1;
return 0;
}
这是int类型转换的写法,相应的,long,float,double等等的类型转换方法一样,统一的说,可以抽象的写成
operator type();只要type是一个类型,包括基本数据类型,自己写的类或者结构体都可以转换。
下面是一段转载,清楚的写明了重载类型转换需要注意的问题
原文链接重载类型转换操作符 遇到的问题
今天我对这段代码产生了质疑:
operator double ()
{
return static_cast <double> (sum)
/static_cast <double> (num);
}
我感觉应该是这样:
double operator double ()
{
return static_cast <double> (sum)
/static_cast <double> (num);
}
于是我就在csdn上发了一个贴问了问,经过zhangweiit,mstlq,djjlove_2008,taodm(非常感谢他们)的指点后明白了这是C++的语法规则,我居然不知道。于是我翻开了久违了的《C++ primer》第四版P454,进行了整理(摘抄),希望掌握这个知识点,也希望看到这篇文章的人也掌握这个知识点。
转换操作符
转换操作符(conversion operator)是一种特殊的类成员函数。它定义将类类型值转变为其他类型值的转换。转换操作符在类定义体内声明,在保留字operator之后跟着转换的目标类型:
class SmallInt
{
public:
SmallInt(int i=0); val(i)
{
if(i < 0 || i > 255)
{
throw std::out_of_range("Bad SmallInt intializer");
}
}
operator int() const
{
return val;
}
private:
std::size_t val;
};
转换函数采用如下通用形式:
operator type();
这里,type表示内置类型名、类类型名或有类型别名所定义的名字。对任何可作为函数的返回类型(除了void之外)。一般而言,不允许转换为数组或函数类型,转换为指针类型(数据和函数指针)以及引用类型是可以的。
注解: 转换函数必须是成员函数,不能指定返回类型,并且形参表必须为空。
下述所有的声明都是错误的:
operator int(Small Int& ); // error:nonmember
class SmallInt
{
public:
int operator int(); // error: return list
operator int(int = 0); // error:parameter list
// ...
};
虽然转换函数不能指定返回类型,但是每个转换函数必须显示返回一个指定的值。例如,operator int返回一个int值;如果定义operator Sales_item,它将返回一个Sales_item对象,诸如此类。
最佳实践: 转换函数一般不应该改变被转换的对象。因此,转换操作符通常应定义为const成员。
1、使用类类型转换
只要存在转换,编译器将在可以使用内置转换的地方自动调用它
在表达式中:
SmallInt si;
double dval;
si >= dval // si converted to int and then convert to bool
在条件中:
if(si) // si convert to int and then convert to bool
将实参传给函数或 从函数返回值:
int calc(int);
SmallInt si;
int i = calc(si); // convert si to int and call calc
作为重载操作符的操作数:
// convert si to int then call << on the int value
cout << si << endl;
在显示类型转换中:
int ival;
SmallInt si = 3.54;
// instruct compiler to cast si to int
ival = static_cast<int>(si) + 3;
2、类类型转换和标准转换
使用转换函数时,被转换的类型不必与所在需要的类型完全匹配。必要时可在类类型转换之后跟上标准转换以获得想要的类型。例如,在一个SmallInt对象与一个double值的比较中:
SmallInt si;
double dval;
si >= dval // si converted to int and then convert to double.
首先将si从SmallInt对象转换为int值,然后将该int值转换为double值。
3、只能应用一个类类型转换
注解:类类型转换之后再跟另一个类类型转换。如果需要多个类类型转换,则代码将出错。
例如,假定有一个类Integral,它可以转换为SmallInt但不能转换为int:
// class to hold unsigned integral values
class Integral
{
public:
Integral(int i = 0):val(i)
{
}
operator SmallInt()const
{
return val % 256;
}
private:
std::size_t val;
};
可以在需要SmallInt的地方使用Integral,但不能再需要int的地方使用Integral:
int calc(int);
Integral intVal;
SmallInt si(intVal); // ok:convert intVal to Small Int and copy to si
int i = calc(si); // ok:convert si to int and call calc
int j = calc(intVal);// error:on convertion to int from Integral
创建si时使用SmallInt复制构造函数。首先调用Integral转换操作符产生一个SmallInt类型的临时值,将int_val对象转换为SmallInt对象。然后(合成的)复制构造函数使用该对象值初始化si。
第一个calc调用也是正确的:将实参si自动转换为int,然后将int值传给函数。
第二个calc调用时错误的:没有从Integral到int的直接转换。从Intergral获得int需要两次类类型转换:首先从Intergral到SmallInt,然后从SmallInt到int。但是,语言只是允许一个类类型转换,所以该调用出错。
4.标准转换可放在类类型转换之前
使用构造函数执行隐式转换的时候,构造函数的形参类型不必与所提供的类型完全匹配。例如,下面的代码调用SmallInt类中定义的构造函数SmallInt(int)将sobj转换为SmallInt类型:
void calc(SmallInt);
short sobj;
// sobj prometed from short to int
// that int converted to SmallInt through the SmallInt(int) constructor
calc(sobj);
如果需要,在调用构造函数执行类类型转换之前,可将一个标准转换序列应用于实参。为了调用函数calc(),应用标准转换将dobj从double类型转换为int类型,然后调用构造函数SmallInt(int)将转换结果转换为SmallInt类型。
本文完
转载请表明出处,谢谢
2010-08-19
在需要做数据类型转换时,一般显式的写法是:
[cpp] view
plain copy
<span style="font-size:18px;">type1 i;
type2 d;
i = (type1)d; //显式的写类型转,把d从type2类型转为type1类型</span>
这种写法不能做到无缝转换,也就是直接写 i = d,而不需要显式的写(type1)来向编译器表明类型转换,要做到这点就需要介绍一下“类型转换操作符”,拿最简单的基本类型封包解包来举例:
[cpp] view
plain copy
class Integer
{
public:
Integer(int v);
Integer& opetaror =(const int &v); //重载赋值操作符,可以做到 Integer i = 10;//把i当基本数据类型使用
operator int(); //重载类型转换操作符,可以做到int i; Integer it; i = it; //it直接转为int类型,然后赋值给i
private:
int data;
};
Integer::Integer(int v)
{
data = v;
}
/*!
*@brief 重载赋值操作符,可以做到 Integer i = 10;//把i当基本数据类型使用
*/
Integer& Integer::opetaror =(const int &v)
{
data = v;
return *this;
}
/*!
*@brief 重载类型转换操作符,可以做到int i; Integer it; i = it; //it直接转为int类型,然后赋值给i
*/
Integer::operator int()
{
return data;
}
#include <iostream>
using namespace std;
int main()
{
Integer integer1(10); //调用构造函数进行初始化
Integer integer2;
int i1 = 10;
integer2 = i1; //调用=赋值操作符进行赋值
//下面测试类型转换操作符的应用
int i2;
i2 = integer1; //integer1是Integer类型,这里直接把Integer类型转换为int,然后赋值给i2
//如果没有重载了int(),需要类型转换的话,这里必须写成 i2 = (int)integer1;
return 0;
}
这是int类型转换的写法,相应的,long,float,double等等的类型转换方法一样,统一的说,可以抽象的写成
operator type();只要type是一个类型,包括基本数据类型,自己写的类或者结构体都可以转换。
下面是一段转载,清楚的写明了重载类型转换需要注意的问题
原文链接重载类型转换操作符 遇到的问题
今天我对这段代码产生了质疑:
operator double ()
{
return static_cast <double> (sum)
/static_cast <double> (num);
}
我感觉应该是这样:
double operator double ()
{
return static_cast <double> (sum)
/static_cast <double> (num);
}
于是我就在csdn上发了一个贴问了问,经过zhangweiit,mstlq,djjlove_2008,taodm(非常感谢他们)的指点后明白了这是C++的语法规则,我居然不知道。于是我翻开了久违了的《C++ primer》第四版P454,进行了整理(摘抄),希望掌握这个知识点,也希望看到这篇文章的人也掌握这个知识点。
转换操作符
转换操作符(conversion operator)是一种特殊的类成员函数。它定义将类类型值转变为其他类型值的转换。转换操作符在类定义体内声明,在保留字operator之后跟着转换的目标类型:
class SmallInt
{
public:
SmallInt(int i=0); val(i)
{
if(i < 0 || i > 255)
{
throw std::out_of_range("Bad SmallInt intializer");
}
}
operator int() const
{
return val;
}
private:
std::size_t val;
};
转换函数采用如下通用形式:
operator type();
这里,type表示内置类型名、类类型名或有类型别名所定义的名字。对任何可作为函数的返回类型(除了void之外)。一般而言,不允许转换为数组或函数类型,转换为指针类型(数据和函数指针)以及引用类型是可以的。
注解: 转换函数必须是成员函数,不能指定返回类型,并且形参表必须为空。
下述所有的声明都是错误的:
operator int(Small Int& ); // error:nonmember
class SmallInt
{
public:
int operator int(); // error: return list
operator int(int = 0); // error:parameter list
// ...
};
虽然转换函数不能指定返回类型,但是每个转换函数必须显示返回一个指定的值。例如,operator int返回一个int值;如果定义operator Sales_item,它将返回一个Sales_item对象,诸如此类。
最佳实践: 转换函数一般不应该改变被转换的对象。因此,转换操作符通常应定义为const成员。
1、使用类类型转换
只要存在转换,编译器将在可以使用内置转换的地方自动调用它
在表达式中:
SmallInt si;
double dval;
si >= dval // si converted to int and then convert to bool
在条件中:
if(si) // si convert to int and then convert to bool
将实参传给函数或 从函数返回值:
int calc(int);
SmallInt si;
int i = calc(si); // convert si to int and call calc
作为重载操作符的操作数:
// convert si to int then call << on the int value
cout << si << endl;
在显示类型转换中:
int ival;
SmallInt si = 3.54;
// instruct compiler to cast si to int
ival = static_cast<int>(si) + 3;
2、类类型转换和标准转换
使用转换函数时,被转换的类型不必与所在需要的类型完全匹配。必要时可在类类型转换之后跟上标准转换以获得想要的类型。例如,在一个SmallInt对象与一个double值的比较中:
SmallInt si;
double dval;
si >= dval // si converted to int and then convert to double.
首先将si从SmallInt对象转换为int值,然后将该int值转换为double值。
3、只能应用一个类类型转换
注解:类类型转换之后再跟另一个类类型转换。如果需要多个类类型转换,则代码将出错。
例如,假定有一个类Integral,它可以转换为SmallInt但不能转换为int:
// class to hold unsigned integral values
class Integral
{
public:
Integral(int i = 0):val(i)
{
}
operator SmallInt()const
{
return val % 256;
}
private:
std::size_t val;
};
可以在需要SmallInt的地方使用Integral,但不能再需要int的地方使用Integral:
int calc(int);
Integral intVal;
SmallInt si(intVal); // ok:convert intVal to Small Int and copy to si
int i = calc(si); // ok:convert si to int and call calc
int j = calc(intVal);// error:on convertion to int from Integral
创建si时使用SmallInt复制构造函数。首先调用Integral转换操作符产生一个SmallInt类型的临时值,将int_val对象转换为SmallInt对象。然后(合成的)复制构造函数使用该对象值初始化si。
第一个calc调用也是正确的:将实参si自动转换为int,然后将int值传给函数。
第二个calc调用时错误的:没有从Integral到int的直接转换。从Intergral获得int需要两次类类型转换:首先从Intergral到SmallInt,然后从SmallInt到int。但是,语言只是允许一个类类型转换,所以该调用出错。
4.标准转换可放在类类型转换之前
使用构造函数执行隐式转换的时候,构造函数的形参类型不必与所提供的类型完全匹配。例如,下面的代码调用SmallInt类中定义的构造函数SmallInt(int)将sobj转换为SmallInt类型:
void calc(SmallInt);
short sobj;
// sobj prometed from short to int
// that int converted to SmallInt through the SmallInt(int) constructor
calc(sobj);
如果需要,在调用构造函数执行类类型转换之前,可将一个标准转换序列应用于实参。为了调用函数calc(),应用标准转换将dobj从double类型转换为int类型,然后调用构造函数SmallInt(int)将转换结果转换为SmallInt类型。
本文完
转载请表明出处,谢谢
2010-08-19
相关文章推荐
- WIndow下使用QT C++开发生成带Logo的二维码的程序
- C++ Primer学习笔记——顺序容器操作
- C语言scanf函数详解
- c++ const在重载overload和覆盖override上使用区别
- c++primer5e学习笔记,第三章
- C语言实现循环队列
- 解决VS2010子目录中的.cpp文件引用上一级目录的stdafx.h找不到定义的问题
- C语言可变参函数的实现原理浅析
- 快速排序---C语言实现
- c++拷贝函数
- [c++基础]valarray模板详解
- 栈的简单实现——使用C++容器库(STL Stack)
- C++面向对象编程:对象的内存分配与静态成员
- 1012. The Best Rank (25)
- C++动态调用DLL
- 理解C语言——从小菜到大神的晋级之路(8)——数组、指针和字符串
- C++ 经常使用类 string类
- C语言之数值计算--级数算法
- C语言之数值计算--级数算法
- C语言之数值计算--级数算法