关于重载 Overloading,最基本的是根据如下两个特性:html
其实,函数重载也没啥多余值得说的东西。ios
c++的操蛋属性:本身为一档,空一档,其余随意。c++
UB_stack a; UB_stack b = a; // copy
auto c = a; auto d {a}; // (or auto d = {a}), deduced type is std::initializer_list
这是一个抓狂的问题,详见:http://scottmeyers.blogspot.com.au/2014/03/if-braced-initializers-have-no-type-why.html
函数
今日一乐:为什么感受到了Scott对chinese edition是黑白版本的好奇和无奈。this
Goto: C++ 重载运算符和重载函数spa
下面是:可重载的运算符列表.net
双目算术运算符 | + (加),-(减),*(乘),/(除),% (取模) |
关系运算符 | ==(等于),!= (不等于),< (小于),> (大于>,<=(小于等于),>=(大于等于) |
逻辑运算符 | ||(逻辑或),&&(逻辑与),!(逻辑非) |
单目运算符 | + (正),-(负),*(指针),&(取地址) |
自增自减运算符 | ++(自增),--(自减) |
位运算符 | | (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移) |
赋值运算符 | =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>= |
空间申请与释放 | new, delete, new[ ] , delete[] |
其余运算符 | ()(函数调用),->(成员访问),,(逗号),[](下标) |
下面是:不可重载的运算符列表指针
成员访问运算符 | . |
成员指针访问运算符 | .*, ->* |
域运算符 | :: |
长度运算符 | sizeof |
条件运算符 | ? |
预处理符号 | # |
序号 | 运算符和实例 |
---|---|
1 | 一元运算符重载 |
2 | 二元运算符重载 |
3 | 关系运算符重载 |
4 | 输入/输出运算符重载 |
5 | ++ 和 -- 运算符重载 |
6 | 赋值运算符重载 |
7 | 函数调用运算符 () 重载 |
8 | 下标运算符 [] 重载 |
9 | 类成员访问运算符 -> 重载 |
重载符号: ==code
声明关键字operator,以及紧跟其后的一个c++预约义的操做符。举例以下:htm
// 申明关键字
class person{ private: int age; public: person(int a){ this->age=a; }
inline bool operator == (const person &ps) const; };
// 实现方式以下 inline bool person::operator == (const person &ps) const { if (this->age==ps.age) // 这里的this看上去是“符号”左边的类 return true; return false; }
// 调用方式以下 #include using namespace std; int main() { person p1(10); person p2(20); if(p1==p2) cout<<”the age is equal!”< return 0; }
重载符号: >>, <<, +, +=
包括:(1) 输入输出;(2) 自增自减;(3) 运算
#include <iostream> #include <vector> #include <algorithm> #include <iterator> #include <UB_stack.h>
using namespace std; class Test { public: Test(int x, int y):a{x},b{y}{} // The output operator must be defined as a friend function // and is usually a non-member function. // The input operator is similar.
friend ostream& operator << (ostream&, const Test &); friend istream& operator >> (istream&, Test&); friend Test operator +(const Test&, const Test&);// Usually implemented as a member function.
Test& operator += (const Test &); int returnA(void); void init(void); private: int a; int b; }; /******************************************************************************/
void Test::init(void) { this->a = 1; this->b = 1; } int Test::returnA(void) { return (this->a); } ostream& operator << (ostream &os, const Test &t) { os << t.a << " " << t.b << endl; } istream& operator >> (istream &is, Test &t) { is >> t.a >> t.b; } Test& Test::operator += (const Test &t) { this->a += t.a; this->b += t.b; return *this; } Test operator +(const Test &t1, const Test &t2) { Test ret = t1; ret += t2; return ret; } /******************************************************************************/
class SmallInt { public: friend ostream& operator << (ostream &os, const SmallInt &s); friend bool operator < (const SmallInt&, const SmallInt&); SmallInt(int v): value_{v} {} private: int value_; }; bool operator < (const SmallInt &rhs,const SmallInt &lhs) { return rhs.value_ <= lhs.value_; } std::ostream& operator<<(std::ostream &os, const SmallInt &s) { os << s.value_; return os; } /******************************************************************************/
int main() { cout << "Hello World!" << endl; Test t1{1, 2}; Test t2{10, 20}; /* * I/O Operators */ cout << t1 << t2; cin >> t2; cout << t1 << t2; t1.init(); t2.init(); /* * Compound Assignment Operators */ t2 += t1; cout << t2; /* * Arithmetic Operators */ cout << t1+t2; /* * Relational Operators * ... */
/* * Using the STL Sort and Copy Algorithms */ vector<SmallInt> vec{SmallInt{3}, SmallInt{1}, SmallInt{2}}; sort(vec.begin(), vec.end()); copy(vec.begin(), vec.end(), std::ostream_iterator<SmallInt>(std::cout, " ")); return 0; }
Ref: 有的操做符重载函数只能是友元函数
根本缘由:this 必须是第一个参数,且 this 默认是 private 的。
重载符号: =
返回void,只是”赋值“的简单版本:https://www.runoob.com/cplusplus/assignment-operators-overloading.html
重载符号: [ ]
* 定义实例:
class SafeArray { public: SafeArray(int s); SafeArray(const int v[], int s); ~SafeArray() {delete[] values;} int& operator [] (int i); int operator [] (int i) const; private: int size; int *values; }; SafeArray::SafeArray(int s) : size{s}, values{new int[size]} {} SafeArray::SafeArray(const int v[], int s) : size{s} { values = new int[size]; for (int i = 0; i < size; i++) { values[i] = v[i]; } } int& SafeArray::operator [](int index) { assert((index >= 0) && (index < size)); return values[index]; } int SafeArray::operator [](int index) const { // 常函数不能修改 函数内的成员 assert((index >= 0) && (index < size)); return values[index]; }
* 使用样例:
SafeArray s{10}; // s[12] = 2; //这算是两个operator,比较难,怎么搞?
cout << s[2] << endl;
Increment and Decrement Operators
重载符号: ++, --
后缀法加了一个参数,有点意思。
From: https://www.runoob.com/cplusplus/increment-decrement-operators-overloading.html
#include <iostream> using namespace std; class Time { private: int hours; // 0 到 23 int minutes; // 0 到 59
public: // 所需的构造函数 Time(){ hours = 0; minutes = 0; } Time(int h, int m){ hours = h; minutes = m; }
// 显示时间的方法 void displayTime() { cout << "H: " << hours << " M:" << minutes <<endl; }
// 重载前缀递增运算符( ++ ) Time operator++ () { ++minutes; // 对象加 1 if(minutes >= 60) { ++hours; minutes -= 60; } return Time(hours, minutes); }
// 重载后缀递增运算符( ++ ) Time operator++( int ) { // 保存原始值 Time T(hours, minutes); // 对象加 1 ++minutes; if(minutes >= 60) { ++hours; minutes -= 60; } // 返回旧的原始值 return T; } };
------------------------------------------------------------- int main() { Time T1(11, 59), T2(10,40); ++T1; // T1 加 1 T1.displayTime(); // 显示 T1 ++T1; // T1 再加 1 T1.displayTime(); // 显示 T1 T2++; // T2 加 1 T2.displayTime(); // 显示 T2 T2++; // T2 再加 1 T2.displayTime(); // 显示 T2 return 0; }
重载符号: -->, *
Ref: C++ 类成员访问运算符 -> 重载
-> must be a member function and * is usually a member.
(Here 简介)
貌似不错的智能指针的博文:http://www.cnblogs.com/lanxuezaipiao/p/4132096.html
The Basic Idea Behind All Smart Pointers
Conversion operators must be defined as member functions. They
do not take any parameters, nor do they specify a return type.
Typically conversions don’t modify the object and are declared
const.
若是去掉explicit,则User code中的line 2便可成立。
explicit: 声明为explicit的构造函数不能在隐式转换中使用。