在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;
}