C++之运算符重载
来源:互联网 发布:烯牛数据 编辑:程序博客网 时间:2024/06/05 18:19
在C语言和C++中,一般的运算符只能对基本类型数据进行操作,而不支持用户自定义类型,比如下面:
#include <iostream>using namespace std;class Int{public: Int(int i = 0):m_i = i {} ~Int() {}private: int m_i;}int main(){ Int S1(2); Int S2(1); S2 = S2 + S1; cout << "S2 = " << S2 << endl;
在上述程序段中,执行完成后出现erro:
[root@localhost Desktop]# g++ test.cpp
test.cpp:13:1: error: expected ‘;’ after class definition
}
^
test.cpp: In constructor ‘Int::Int(int)’:
test.cpp:7:24: error: expected ‘(’ before ‘=’ token
Int(int i = 0):m_i = i
^
test.cpp:7:24: error: expected ‘{’ before ‘=’ token
test.cpp: In function ‘int main()’:
test.cpp:19:13: error: no match for ‘operator+’ (operand types are ‘Int’ and ‘Int’)
S2 = S2 + S1;
^
test.cpp:20:21: error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream’ and ‘Int’)
cout << “S2 = ” << S2 << endl;
^
由此看出,一般运算符对用户自定义类不适用,为了解决这一问题,C++中提出了运算符重在这一定义,用户可根据自己需求重新定义运算符。
运算符重载形式有两种,重载为类的成员函数和重载为类的友元函数
运算符重载规则如下:
1、 C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已有的运算符。
【不能重载的运算符只有五个:
成员运算符: “.” ; 指针运算符: “ * ”
作用域运算符: “ :: ” ; “ sizeof ”;
条件运算符: “?:” 】
2、 重载之后运算符的优先级和结合性都不会改变。
3、 运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。
4、若一个运算符的操作需要修改对象的状态,选择重载为成员函数较好。
5、若运算符所需的操作数(尤其是第一个操作数)希望有隐式类型转换,则只能选用友元函数。
6、当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(或者是对该类对象的引用)。如果左边的操作数必须是一个不同类的对象,或者是一个内部 类型的对象,该运算符函数必须作为一个友元函数来实现。
一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数。
C++提供4个类型转换函数:reinterpret_cast(在编译期间实现转换)、const_cast(在编译期间实现转换)、stactic_cast(在编译期间实现转换)、dynamic_cast(在运行期间实现转换,并可以返回转换成功与否的标志)。
运算符重载示例:
#include <iostream>using namespace std;class Int;ostream& operator<<(ostream &out, const Int &i);class Int{ //friend class Int; friend ostream& operator<<(ostream &out, const Int &i);public: Int(int i = 0):m_i(i) {} ~Int() {}public: /**********算术运算符***********/ Int operator+(const Int &i); Int operator-(const Int &i); Int operator*(const Int &i); Int operator/(const Int &i); Int operator%(const Int &i); Int operator^(const Int &i); Int operator++(); //++a Int operator++(int); //a++ Int& operator--(); //--a Int operator--(int); //a-- /***********赋值运算符***********/ void operator+=(const Int &i); void operator-=(const Int &i); void operator*=(const Int &i); void operator/=(const Int &i); void operator%=(const Int &i); Int& operator>>=(int n); //>>=a Int& operator<<=(int n); //<<=a Int& operator+(); //+a Int& operator-(); //-a /************位操作运算符***********/ Int& operator~(); //~a Int& operator!(); //!a /************条件运算符*************/ bool operator==(const Int &i); bool operator<(const Int &i); bool operator>(const Int &i); bool operator<=(const Int &i); bool operator>=(const Int &i); /**************位操作运算符***********/ Int& operator>>(int n); //>>a Int& operator<<(int n); //<<a Int operator&(const Int &i); Int operator|(const Int &i); /**************逻辑运算符************/ bool operator&&(const Int &i); bool operator||(const Int &i);private: int m_i;};ostream& operator<<(ostream &out, const Int &i){ out << (i.m_i); return out;}Int Int::operator+(const Int &i){ return Int(m_i + i.m_i);}Int Int::operator-(const Int &i){ return Int(m_i - i.m_i);}Int Int::operator*(const Int &i){ return Int(m_i * i.m_i);}Int Int::operator/(const Int &i){ return Int(m_i / i.m_i);}void Int::operator+=(const Int &i){ m_i += i.m_i;}void Int::operator-=(const Int &i){ m_i -= i.m_i;}void Int::operator*=(const Int &i){ m_i *= i.m_i;}void Int::operator/=(const Int &i){ m_i /= i.m_i;}Int Int::operator%(const Int &i){ return m_i % i.m_i;}Int Int::operator^(const Int &i){ return m_i ^ i.m_i;}void Int::operator%=(const Int &i){ m_i %= i.m_i;}void Int::operator^=(const Int &i){ m_i ^= i.m_i;}#if 1Int Int::operator++() //++a{ m_i += 1; return *this;}#endifInt Int::operator++(int) //a++{ Int temp(m_i); m_i += 1; return temp;}Int& Int::operator--() //--a{ m_i -= 1; return *this;}Int Int::operator--(int) //a--{ Int temp(*this); m_i -= 1; return temp;}Int& Int::operator+(){ m_i = +m_i; return *this;}Int& Int::operator-(){ m_i = -m_i; return *this;}Int& Int::operator~(){ m_i = ~m_i; return *this;}Int& Int::operator!(){ m_i = !m_i; return *this;}bool Int::operator==(const Int &i){ return m_i == i.m_i;}bool Int::operator!=(const Int &i){ return m_i != i.m_i;}bool Int::operator<(const Int &i){ return m_i < i.m_i;}bool Int::operator>(const Int &i){ return m_i > i.m_i;}bool Int::operator<=(const Int &i){ return m_i <= i.m_i;}bool Int::operator>=(const Int &i){ return m_i >= i.m_i;}Int& Int::operator>>(int n) //>>a{ m_i = m_i >> n; return *this;}Int& Int::operator<<(int n) //<<a{ m_i = m_i << n; return *this;}Int& Int::operator>>=(int n) //>>={ m_i >>= n; return *this;}Int& Int::operator<<=(int n) //<<={ m_i <<= n; return *this;}Int Int::operator&(const Int &i) { Int temp; temp.m_i = m_i & i.m_i; return temp;}Int Int::operator|(const Int &i){ Int temp; temp.m_i = m_i | i.m_i; return temp;}bool Int::operator&&(const Int &i) { return m_i && i.m_i;}bool Int::operator||(const Int &i){ return m_i || i.m_i;}int main(){ Int S(10); Int S1(1); Int S2 = S / S1; Int S3(0); S3 = !S3; cour << "S3 = " << 3S << endl; S3 ^= 3; cout << "S3 = " << S3 << endl; cout << ++S3 + S1 << S3 << endl; cout << S1 + S3++ << S3 <<endl; cout << "S1 & S3 = " << S1 & S3 << endl; cout << "S1 | S3 = " << S1 | S3 << endl; if(S && S3){ cout << "S && S3 is true!" << endl; }else{ cout << "S && S3 is false" << endl; } if(S || S3){ cout << "S || S3 is true!" << endl; }else{ cout << "S || S3 is false!" << endl; } cout << "S = " << S << endl;; cout << "S1 = " << S1 << endl; cout << "S2 = " << S2 << endl; cout << "S3 = " << S3 << endl; S1 = S1 >> 1; cout << "S1 >> 1, S1 = " << S1 << endl; S2 = S2 << 1; cout << "S2 << 1, S2 = " << S2 << endl; S1 <<= 1; cout << "S1 << 1, S1 = " << S1 << endl; S2 >>= 1; cout << "S2 >> 1, S2 = " << S2 << endl; }
- 【C++】C++大数之运算符重载
- 【C++】之【运算符重载函数】
- C语言之重载运算符()/[]/++/->等运算符
- C++-运算符重载
- [C++]重载运算符
- C#:运算符重载
- c++-++运算符重载
- C++:重载运算符
- 运算符重载(C++)
- [c++]运算符重载
- 【C++】运算符重载
- C++--------------------------------------------运算符重载
- C#:运算符重载
- C++:运算符重载
- C++:运算符重载
- C#:运算符重载
- [C++]运算符重载
- 【c++】运算符重载
- MySql远程不能登录问题解决办法
- 数组分段查找
- Java笔试题分类总结--String
- red5使用教程
- ORACLE 创建序列
- C++之运算符重载
- Linux下DIR,dirent,stat 结构体
- 面试问题,将字符串、字符串单词倒叙输出
- cocos2d-Lua08常用SocostudioUI组件及编辑器
- 第一个程序(C#)_使用Visual Studio
- android工具2——MD5加密
- 【学习笔记----数据结构03--线性链表】
- Hadoop和spark通信机制
- 【笔记】 《js权威指南》- 第17章 事件处理 - 17.2 - 17.3