您的位置:首页 > 编程语言 > C语言/C++

C++之运算符重载

2016-04-08 16:11 429 查看
在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 1
Int Int::operator++()              //++a
{
m_i += 1;
return *this;
}
#endif
Int 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: