运算符重载¶
为了使用起来方便,增强功能。运算符重载就是一个函数,函数的名称要加上operator。
可重载运算符如下:
| 类型 | 运算符 |
|---|---|
| 算术 | +、-、*、/、% |
| 位运算 | ^、&、|、~、<<、>> |
| 逻辑 | !、&&、|| |
| 比较 | <、>、<=、>=、==、!= |
| 赋值与复合赋值 | =、+=、-=、*=、/=、%=、^=、&=、|=、<<=、>>= |
| 自增与自减 | ++、-- |
| 逗号 | , |
| 下标与函数调用 | []、() |
| 成员访问 | ->、->* |
| 内存分配与释放 | new、new[]、delete、delete[] |
当前标准还支持 <=>(三路比较)和 co_await(协程等待)的重载。+、-、*、& 的一元和二元形式均可重载。
以下运算符不能重载:
| 运算符 | 用途 |
|---|---|
:: |
作用域解析,例如 std::cout |
?: |
条件运算,例如 condition ? a : b |
. |
通过对象访问成员,例如 object.member |
.* |
通过对象与成员指针访问成员,例如 object.*member_pointer |
来源:C++ 标准草案:运算符重载。
重载加号运算符¶
三个类,Dog,Cat,Person。
class Dog
{
public:
int d;
};
class Cat
{
public:
int c;
};
class Person
{
public:
int p;
};
//运算符重载实际上就是一个函数
Cat operator+(const Person& p, const Dog& d)
{
Cat cat;
cat.c = p.p + d.d;
return cat;
}
void testOperator()
{
Dog d;
Cat c;
Person x;
d.d = 100;
x.p = 200;
c = x + d;
//也可以直接调用
//c = x.operator+(d);
cout << c.c << endl;
}
上面的运算符重载函数是个全局函数,也可以做成一个成员函数。
class Person
{
public:
Cat operator+(const Dog& d)
{
Cat cat;
cat.c = p + d.d;
return cat;
}
public:
int p;
};
例:C++重载字符串加号运算符,拼接字符串。
例:
销售卖书,两个销售一共卖多少,每个销售卖的数量和卖了多少钱不一样。计算一共卖了多少本,一共卖了多少钱。
class Sale
{
//友元函数 可以访问类中的私有成员
friend Sale operator+(const Sale &left, const Sale &right);
public:
/// 构造函数
/// - Parameters:
/// - book: 什么书
/// - units: 卖多少本
/// - price: 卖多少钱
Sale(const string &book, unsigned units, double price)
: name(book),units_sold(units),revenue(units * price)
{}
/// 求平均每本多少钱
double avg_price() const
{
return revenue / units_sold;
}
//成员变量 为了调试,需要改成public
//private:
public:
string name;
unsigned units_sold;
double revenue;
};
//运算符重载函数做成全局的函数
Sale operator+(const Sale &left, const Sale &right)
{
Sale sale(left);
sale.units_sold += right.units_sold;
sale.revenue += right.revenue;
return sale;
}
//调用
void test()
{
Sale sale1("C++ Programming",10,50.0);
Sale sale2("C++ Programming",2,60.0);
Sale sale3 = sale1 + sale2;
cout << sale3.units_sold << ", " << sale3.avg_price() << endl;
}
成员函数还是非成员函数¶
| 运算符 | 实现方式 |
|---|---|
=、()、[]、-> |
必须使用成员函数 |
一元运算符,如 !、~、++、-- |
通常使用成员函数 |
+=、-=、/=、*=、^=、&=、|=、%=、>>=、<<= |
通常使用成员函数 |
其它普通二元运算符,如 +、-、==、<<、>>、->* |
通常使用非成员函数;也可以使用成员函数 |
“必须”是语言要求,“通常”是实现建议。->* 可使用成员函数或非成员函数。以 std::cout << object 形式输出自定义对象时,左操作数是流对象,通常将重载函数实现为非成员函数。
来源:C++ 标准草案:赋值、函数调用、下标、成员访问、普通二元运算符。