c++运算符重载---20
原创博文,转载请标明出处--周学伟 http://www.cnblogs.com/zxouxuewei/
c++的一大特性就是重载(overload),通过重载可以把功能相似的几个函数合为一个,使得程序更加简洁、高效。
在c++中不止函数可以重载,运算符也可以重载。由于一般数据类型间的运算符没有重载的必要,所以运算符重载主要是面向对象之间的。
1.一般运算符重载
在进行对象之间的运算时,程序会调用与运算符相对应的函数进行处理,所以运算符重载有两种方式:成员函数和友元函数。成员函数的形式比较简单,就是在类里面定义了一个与操作符相关的函数。友元函数因为没有this指针,所以形参会多一个。
class A
{
public:
A(int d):data(d){}
A operator+(A&);//成员函数
A operator-(A&);
A operator*(A&);
A operator/(A&);
A operator%(A&);
friend A operator+(A&,A&);//友元函数
friend A operator-(A&,A&);
friend A operator*(A&,A&);
friend A operator/(A&,A&);
friend A operator%(A&,A&);
private:
int data;
};
//成员函数的形式
A A::operator+(A &a)
{
return A(data+a.data);
}
A A::operator-(A &a)
{
return A(data-a.data);
}
A A::operator*(A &a)
{
return A(data*a.data);
}
A A::operator/(A &a)
{
return A(data/a.data);
}
A A::operator%(A &a)
{
return A(data%a.data);
}
//友元函数的形式
A operator+(A &a1,A &a2)
{
return A(a1.data+a2.data);
}
A operator-(A &a1,A &a2)
{
return A(a1.data-a2.data);
}
A operator*(A &a1,A &a2)
{
return A(a1.data*a2.data);
}
A operator/(A &a1,A &a2)
{
return A(a1.data/a2.data);
}
A operator%(A &a1,A &a2)
{
return A(a1.data%a2.data);
}
//然后我们就可以对类的对象进行+、-、*、/了。
void main(void)
{
A a1(),a2(),a3();
a1=a2.operator+(a3);
}
eg:
/***************友元函数重载1******************/
#include <iostream>
using namespace std; typedef unsigned int Uint32; class testStruction
{
public:
testStruction(Uint32 hundred)
:hundredValue(hundred){} friend testStruction operator +(const testStruction&, const testStruction&);
friend testStruction operator -(const testStruction&, const testStruction&); void displayValue(); private:
Uint32 hundredValue;
}; void testStruction::displayValue()
{
cout <<"hundredValue = "<<this->hundredValue<<endl;
} testStruction operator +(const testStruction& str1, const testStruction& str2)
{
return (str1.hundredValue + str2.hundredValue);
} testStruction operator -(const testStruction& str1, const testStruction& str2)
{
return (str1.hundredValue - str2.hundredValue);
} int main()
{
testStruction structUserA(1003),structUserB(1008); structUserA = structUserA + structUserB;
structUserA.displayValue(); return 0;
} /*********成员函数运算符重载1****************/
#include <iostream>
using namespace std; typedef unsigned int Uint32; class testStruction
{
public:
testStruction(Uint32 hundred)
:hundredValue(hundred){} testStruction operator +(const testStruction&);
testStruction operator -(const testStruction&); void displayValue(); private:
Uint32 hundredValue;
}; void testStruction::displayValue()
{
cout <<"hundredValue = "<<this->hundredValue<<endl;
} testStruction testStruction::operator +(const testStruction& str1)
{
return testStruction(this->hundredValue + str1.hundredValue);
}
testStruction testStruction::operator -(const testStruction& str1)
{
return testStruction(this->hundredValue - str1.hundredValue);
} int main()
{
testStruction structUserA(1003);
testStruction structUserB(1000); structUserA = structUserA - structUserB;
structUserA.displayValue(); structUserA = structUserA + structUserB;
structUserA.displayValue(); return 0;
}
2.关系运算符重载
因为函数体比较简单,后面我就只给出成员函数形式的函数声明了,关系运算符有==,!=,<,>,<=,>=。
bool operator == (const A& );
bool operator != (const A& );
bool operator < (const A& );
bool operator <= (const A& );
bool operator > (const A& );
bool operator >= (const A& );
eg:
#include <iostream>
using namespace std; typedef unsigned int Uint32; class testStruction
{
public:
testStruction(Uint32 hundred)
:hundredValue(hundred){} friend bool operator >(const testStruction&, const testStruction&);
friend bool operator <(const testStruction&, const testStruction&); void displayValue(); private:
Uint32 hundredValue;
}; void testStruction::displayValue()
{
cout <<"hundredValue = "<<this->hundredValue<<endl;
} bool operator >(const testStruction& str1, const testStruction& str2)
{
return (str1.hundredValue > str2.hundredValue) ?true :false;
} bool operator <(const testStruction& str1, const testStruction& str2)
{
return (str1.hundredValue < str2.hundredValue) ?true :false;
} int main()
{
testStruction structUserA(),structUserB(); if (structUserA > structUserB)
cout <<"structUserA > structUserB"<<endl;
else
cout <<"structUserA < structUserB"<<endl; if (structUserA < structUserB)
cout <<"structUserA < structUserB"<<endl;
else
cout <<"structUserA > structUserB"<<endl; return ;
}
3.逻辑运算符重载
bool operator || (const A& );
bool operator && (const A& );
bool operator ! ();
4.单目运算符重载
这里的+、-是正负的意思,放在对象前面。
A& operator + ();
A& operator - ();
A* operator & ();
A& operator * ();
5.自增减运算符重载
++和–根据位置的不同有四种情况,都可以重载。
A& operator ++ ();//前置++
A operator ++ (int);//后置++
A& operator --();//前置--
A operator -- (int);//后置--
EG:
#include <iostream>
using namespace std; typedef unsigned int Uint32; class testStruction
{
public:
testStruction(Uint32 hundred)
:hundredValue(hundred){} testStruction& operator ++();
testStruction operator ++(int); void displayValue(); private:
Uint32 hundredValue;
}; void testStruction::displayValue()
{
cout <<"hundredValue = "<<this->hundredValue<<endl;
} testStruction& testStruction::operator ++()
{
++hundredValue;
return *this;
} testStruction testStruction::operator ++(int)
{
testStruction temp(*this);
++hundredValue;
return temp;
} int main()
{
testStruction structUserA(),structUserB(); testStruction C = structUserA++;
C.displayValue(); testStruction D = ++structUserB;
D.displayValue(); return ;
}
6.位运算符重载
按位操作。
A operator | (const A& );
A operator & (const A& );
A operator ^ (const A& );
A operator << (int i);
A operator >> (int i);
A operator ~ ();
7.赋值运算符重载
没有=哦。
A& operator += (const A& );
A& operator -= (const A& );
A& operator *= (const A& );
A& operator /= (const A& );
A& operator %= (const A& );
A& operator &= (const A& );
A& operator |= (const A& );
A& operator ^= (const A& );
A& operator <<= (int i);
A& operator >>= (int i);
8.内存运算符重载
void *operator new(size_t size);
void *operator new(size_t size, int i);
void *operator new[](size_t size);
void operator delete(void*p);
void operator delete(void*p, int i, int j);
void operator delete [](void* p);
9.特殊运算符重载
上面的运算符重载都有两种方式,而下面的运算符只能用一种,特殊吧。 这些运算符的重载只能是成员函数。
A& operator = (const A& );
char operator [] (int i);//返回值不能作为左值
const char* operator () ();
T operator -> ();
//类型转换符
operator char* () const;
operator int ();
operator const char () const;
operator short int () const;
operator long long () const;
//还有很多就不写了
而这些只能以友元函数的形式重载
friend inline ostream &operator << (ostream&, A&);//输出流
friend inline istream &operator >> (istream&, A&);//输入流
10.总结
两种重载方式的比较:
- 一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数。
- 以下一些双目运算符不能重载为类的友元函数:=、()、[]、->。
- 类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。 C++提供4个类型转换函数:reinterpret_cast(在编译期间实现转换)、const_cast(在编译期间实现转换)、stactic_cast(在编译期间实现转换)、dynamic_cast(在运行期间实现转换,并可以返回转换成功与否的标志)。
- 若一个运算符的操作需要修改对象的状态,选择重载为成员函数较好。
- 若运算符所需的操作数(尤其是第一个操作数)希望有隐式类型转换,则只能选用友元函数。
- 当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(或者是对该类对象的引用)。如果左边的操作数必须是一个不同类的对象,或者是一个内部 类型的对象,该运算符函数必须作为一个友元函数来实现。
- 当需要重载运算符具有可交换性时,选择重载为友元函数。
注意事项:
- 除了类属关系运算符”.“、成员指针运算符”.*“、作用域运算符”::“、sizeof运算符和三目运算符”?:“以外,C++中的所有运算符都可以重载。
- 重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。
- 运算符重载实质上是函数重载,因此编译程序对运算符重载的选择,遵循函数重载的选择原则。
- 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。
- 运算符重载不能改变该运算符用于内部类型对象的含义。它只能和用户自定义类型的对象一起使用,或者用于用户自定义类型的对象和内部类型的对象混合使用时。
- 运算符重载是针对新类型数据的实际需要对原有运算符进行的适当的改造,重载的功能应当与原有功能相类似,避免没有目的地使用重载运算符。
c++运算符重载---20的更多相关文章
- C#高级编程笔记2016年10月12日 运算符重载
1.运算符重载:运算符重重载的关键是在对象上不能总是只调用方法或属性,有时还需要做一些其他工作,例如,对数值进行相加.相乘或逻辑操作等.例如,语句if(a==b).对于类,这个语句在默认状态下会比较引 ...
- YTU 2617: B C++时间类的运算符重载
2617: B C++时间类的运算符重载 时间限制: 1 Sec 内存限制: 128 MB 提交: 284 解决: 108 题目描述 C++时间类的运算符重载 定义一个时间类Time,其数据成员为 ...
- swift:高级运算符(位运算符、溢出运算符、优先级和结合性、运算符重载函数)
swift:高级运算符 http://www.cocoachina.com/ios/20140612/8794.html 除了基本操作符中所讲的运算符,Swift还有许多复杂的高级运算符,包括了C语和 ...
- C++之运算符重载(1)
在前一节中曾提到过,C++中运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的.这一系列我将主要讲解C++中有关运算符重载方面的内容.在每一个系列讲解之前,都会有 ...
- C#语言特性-运算符重载
一.C#当中可以进行重载和不可重载的运算符: 1.简单的说明: 1.从上图中可以看到,可以重载的和不可以进行重载的运算符,比较特殊的是第二行和倒数第三行,的运算符,为什么会说它们特殊,是因为(第三行) ...
- C++之------运算符重载
① 什么是运算符重载? 何为C++的运算符重载呢? 其实就是运算符给它重新赋予新的含义或者多重含义.让它有另外一种新的功能. 为什么需要运算符重载? 面向对象中为了实现类的多态性,我们就引用了运算符 ...
- C++学习之运算符重载的总结
C++学习之运算符重载的总结 运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用域不同类型的数据导致不同行为的发生,C++为运算符重载提供了一种方法,即运算符重载函数 ...
- C++ Primer笔记10_运算符重载_赋值运算符_进入/输出操作符
1.颂值运营商 首先来福值运算符引入后面要说的运算符重载.上一节说了构造函数.拷贝构造函数:一个类要想进行更好的控制.须要定义自己的构造函数.拷贝构造函数.析构函数.当然,还有赋值运算符.常说的三大函 ...
- 从零开始学C++之运算符重载(三):完善String类([]、 +、 += 运算符重载)、>>和<<运算符重载
在前面文章中使用过几次String类的例子,现在多重载几个运算符,更加完善一下,并且重载流类运算符. []运算符重载 +运算符重载 +=运算符重载 <<运算符重载 >>运算符重 ...
随机推荐
- Vagrant (1) —— 基本安装与配置(上)
Vagrant (1) -- 基本安装与配置(上) 摘要 基本安装与配置 版本 Vagrant版本: 1.8.1 内容 启动运行 $ vagrant init hashicorp/precise64 ...
- hbase源码系列(二)HTable 探秘
hbase的源码终于搞一个段落了,在接下来的一个月,着重于把看过的源码提炼一下,对一些有意思的主题进行分享一下.继上一篇讲了负载均衡之后,这一篇我们从client开始讲吧,从client到master ...
- python出现UnicodeEncodeError有可能产生的另一个原因
在使用python中,我们都有可能遇到如下的错误: UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ...
- LibreOffice openoffice 区别
LibreOffice的初始版本号码被设置为与OpenOffice.org一致,故初始发布(2010年)即为第三版,并不存在第二版.第一版. 后来,甲骨文宣布停止OpenOffice.org的商业支持 ...
- javascript显示年月日时间代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- [zhuan]《MEF程序设计指南》博文汇总
http://www.cnblogs.com/beniao/archive/2010/08/11/1797537.html 在MEF之前,人们已经提出了许多依赖注入框架来解决应用的扩展性问题,比如OS ...
- Java虚拟机(JVM)体系结构概述及各种性能参数优化总结
转自:http://blog.csdn.net/zhongwen7710/article/details/39213377 第一部分:相关的概念 数据类型 Java虚拟机中,数据类型可以分为两类:基本 ...
- 反编译CMD命令
1.反XML命令 E:\HuaWei Tools\android\apktool-install-windows-r04-brut1 java -jar AXMLPrinter2.jar guide ...
- TP Rate ,FP Rate, Precision, Recall, F-Measure, ROC Area,
TP Rate ,FP Rate, Precision, Recall, F-Measure, ROC Area, https://www.zhihu.com/question/30643044 T/ ...
- 【转】【Python】Python 中文编码报错
用 Python 输出 "Hello, World!",英文没有问题,但是如果你输出中文字符"你好,世界"就有可能会碰到中文编码问题. Python 文件中如果 ...