1. 函数重载
编译器是没有办法通过返回值来确认调用的是哪个函数的。
代码:
#include<iostream>
using namespace std;
int func(int x) {
return 2 * x;
}
double func(double x) {
return x * x;
}
int func(int x, int y) {
return x * y;
}
int main() {
cout << func(2) << endl;//func(int)
cout << func(2.3) << endl; // func(double)
cout << func(2, 4) << endl; // func(int, int)
return 0;
}
冲突形式:参数有默认值
针对这种情况,可以将两个函数进行合并:
#include<iostream>
using namespace std;
//两种调用形式
//func(int)
//func(int, int)
int func(int x, int y = 10) {
return x * y;
}
double func(double x) {
return x * x;
}
int main() {
cout << func(2) << endl;//func(int)
cout << func(2.3) << endl; // func(double)
cout << func(2, 4) << endl; // func(int, int)
return 0;
}
无法通过返回值来做函数重载形式的区分:
2. 重载的意义
3. 友元
若 类外的一个函数 想要访问类内部成员,需要将该函数声明成类的一个友元函数。
形式如下:
class A {
private :
int a;
int b;
public :
A() : a(0), b(0) {}
A(int a, int b): a(a), b(b) {}
A(const A &obj): a(obj.a), b(obj.b) {}
friend A add(const A &obj1, const A &obj2);
};
A add(const A &obj1, const A &obj2) {
A ret(0, 0);
ret.a = obj1.a + obj2.a;
ret.b = obj1.b + obj2.b;
return ret;
}
实例:
#include<iostream>
using namespace std;
class Data {
public:
Data() {}
Data(int x, int y) : x(x), y(y) {
cout << "Data : " << this << endl;
}
friend ostream &operator<<(ostream &out, const Data &d);
private:
int x, y;
};
ostream &operator<<(ostream &out, const Data &d) {
//访问Data的私有属性,需要在Data类中将该函数声明为friend
out << d.x << " " << d.y;
return out;
}
int main() {
Data d(10, 9);
//对<< 进行重载
cout << d << endl;
return 0;
}
友元函数本质上是一个类外部的函数,声明为友元函数后虽然还是类外的函数,但是可以访问类内部的私有属性。
4. 运算符重载(非成员)
4.1 什么符号能被重载?
sizeof
也是运算符,也无法被重载,但是通常不被认为是运算符,而是函数。
注意:new
和delete
是运算符,malloc
是函数。
4.2 类外重载
#include<iostream>
using namespace std;
class Point {
public:
Point();
Point(int x, int y);
private:
friend Point operator+(const Point &a, const Point &b);
friend ostream &operator<<(ostream &out, const Point &p);
int x, y;
};
//委托构造:调用了Point(int, int)构造函数进行构造
Point::Point() : Point(0, 0) {}
Point::Point(int x, int y) : x(x), y(y) {}
//类外重载+号
//第一个参数代表+号左边的变量,第二个代表+号右边的变量
Point operator+(const Point &a, const Point &b) {
Point c(a.x + b.x, a.y + b.y);
return c;
}
//重载<<运算符
//第一个参数代表<<运算符左边的变量,第二个代表<<运算符右边的变量
ostream &operator<<(ostream &out, const Point &p) {
out << "(" << p.x << ", " << p.y << ")";
return out;
}
int main() {
Point a(3, 4);
Point b(7, 9);
Point c = a + b;
cout << a << endl;
cout << b << endl;
cout << c << endl;
return 0;
}
//输出结果:
//(3, 4)
//(7, 9)
//(10, 13)
问:什么是委托构造?
答:Point::Point() : x(0), y(0) {} Point::Point(int x, int y) : x(x), y(y) {}
代码中的第2行是分别对
x
和y
进行赋值,第1行是将x
和y
都赋值为0,所以1行可以委托2行进行构造:Point::Point() : Point(0, 0) {} Point::Point(int x, int y) : x(x), y(y) {}
4.3 类内重载
#include<iostream>
using namespace std;
class Point {
public:
Point();
Point(int x, int y);
//类内重载运算符+,只需要传入一个参数
//因为this指针指向的对象代表了+左边的参数,而传入的参数a代表+右边的参数
Point operator+(const Point &a);
private:
friend Point operator+(const Point &a, const Point &b);
friend ostream &operator<<(ostream &out, const Point &p);
int x, y;
};
Point::Point() : Point(0, 0) {}
Point::Point(int x, int y) : x(x), y(y) {}
//类内重载+
Point Point::operator+(const Point &a) {
cout << "inner operator+" << endl;
Point c(x + a.x, y + a.y);
return c;
}
//类外重载+
Point operator+(const Point &a, const Point &b) {
cout << "outer operator+" << endl;
Point c(a.x + b.x, a.y + b.y);
return c;
}
ostream &operator<<(ostream &out, const Point &p) {
out << "(" << p.x << ", " << p.y << ")";
return out;
}
int main() {
Point a(3, 4);
Point b(7, 9);
Point c = a + b;
cout << a << endl;
cout << b << endl;
cout << c << endl;
return 0;
}
类外重载和类内重载同时存在不会冲突,因为类内重载的优先级更高,同时存在的时候会调用类内重载。
4.4 重载成员函数的原则
- 赋值(
=
)、下标([]
)、调用(()
)、成员访问(->
) 运算符必须重载为成员函数 - 复合赋值运算符一般重载为成员函数
- 改变对象运算状态的运算符和类型密切相关的运算符,一般重载为成员函数,如:自增等
- 具有对称性的运算符可能转换任意一端的对象,通常重载为非成员函数,如:相等,关系和位运算
4.5 重载+=运算符
#include<iostream>
using namespace std;
class Point {
public:
Point();
Point(int x, int y);
//类内重载运算符+,只需要传入一个参数
//因为this指针指向的对象代表了+左边的参数,而传入的参数a代表+右边的参数
Point operator+(const Point &a);
//重载+=运算符
Point &operator+=(int);
private:
friend Point operator+(const Point &a, const Point &b);
friend ostream &operator<<(ostream &out, const Point &p);
int x, y;
};
Point::Point() : Point(0, 0) {}
Point::Point(int x, int y) : x(x), y(y) {}
Point &Point::operator+=(int n) {
x += n, y += n;
return *this;
}
//类内重载+
Point Point::operator+(const Point &a) {
cout << "inner operator+" << endl;
Point c(x + a.x, y + a.y);
return c;
}
//类外重载+
Point operator+(const Point &a, const Point &b) {
cout << "outer operator+" << endl;
Point c(a.x + b.x, a.y + b.y);
return c;
}
ostream &operator<<(ostream &out, const Point &p) {
out << "(" << p.x << ", " << p.y << ")";
return out;
}
int main() {
Point a(3, 4);
Point b(7, 9);
Point c = a + b;
cout << a << endl;
cout << b << endl;
cout << c << endl;
a += 2; //给a的x和y各+2
cout << a << endl;
return 0;
}
注意这两行代码:
Point operator+(const Point &a);
Point &operator+=(int);
为什么重载 +=
运算符返回的是引用?重载 +
运算符返回的是一个新的值?
a += 2;
是作用在a
上。
从逻辑上来讲,这个表达式返回的还是a
的值,所以返回引用;
从功能上来讲,如果连续加(a += 2) += 2;
则必须返回引用,只有前一个+=
表达式返回的是引用,后一个+=
才会继续作用于对象a
上。
运算符的返回值是任意的,并没有规定一定要返回引用。
4.6 [] 运算符的重载
[]
重载出来的对象叫做==数组对象==;
[]
只支持==类内重载==
#include<iostream>
using namespace std;
class Point {
public:
Point();
Point(int x, int y);
//类内重载运算符+,只需要传入一个参数
//因为this指针指向的对象代表了+左边的参数,而传入的参数a代表+右边的参数
Point operator+(const Point &a);
//重载+=运算符
Point &operator+=(int);
int operator[](string s);
private:
friend Point operator+(const Point &a, const Point &b);
friend ostream &operator<<(ostream &out, const Point &p);
int x, y;
};
Point::Point() : Point(0, 0) {}
Point::Point(int x, int y) : x(x), y(y) {}
int Point::operator[](string s) {
if (s == "x") return x;
if (s == "y") return y;
return 0;
}
Point &Point::operator+=(int n) {
x += n, y += n;
return *this;
}
//类内重载+
Point Point::operator+(const Point &a) {
cout << "inner operator+" << endl;
Point c(x + a.x, y + a.y);
return c;
}
//类外重载+
Point operator+(const Point &a, const Point &b) {
cout << "outer operator+" << endl;
Point c(a.x + b.x, a.y + b.y);
return c;
}
ostream &operator<<(ostream &out, const Point &p) {
out << "(" << p.x << ", " << p.y << ")";
return out;
}
int main() {
Point a(3, 4);
Point b(7, 9);
cout << a["x"] << endl;
cout << a["y"] << endl;
Point c = a + b;
cout << a << endl;
cout << b << endl;
cout << c << endl;
a += 2; //给a的x和y各+2
cout << a << endl;
return 0;
}
因为 Point
类重载了 []
运算符,所以所有 Point
类的对象都支持 []
运算符,因此可以在 a
对象后面加上 []
运算符。
a
对象的外在表现像一个数组,但是它的本质还是一个对象。所以将重载了 []
运算符的类产生的对象,叫做数组对象,就是外在表现是一个数组,但是本质上还是一个对象。
4.7 () 运算符的重载
()
重载出来的对象叫做函数对象,也叫==仿函数==;
#include<iostream>
using namespace std;
class ADD {
public :
ADD(int c) : c(c) {}
int operator()(int a, int b) {
return a + b + c;
}
private :
int c;
};
int main() {
ADD add(5);
cout << add(6, 7) << endl; //输出18
return 0;
}
add
对象表现得像个函数,但是本质是个对象,所以叫做函数对象,也叫做可调用对象,也称仿函数。
4.8 -> 运算符的重载
->
(间接引用)重载出来的对象叫做 指针对象。
#include<iostream>
using namespace std;
class Point {
public :
Point();
Point(int x, int y);
//类内重载运算符+,只需要传入一个参数
//因为this指针指向的对象代表了+左边的参数,而传入的参数a代表+右边的参数
Point operator+(const Point &a);
//重载+=运算符
Point &operator+=(int);
//重载[]运算符
int operator[](string s);
int getX() { return x; }
int getY() { return y; }
private :
friend Point operator+(const Point &a, const Point &b);
friend ostream &operator<<(ostream &out, const Point &p);
int x, y;
};
class PPoint {
public :
PPoint(Point *p) : p(p) {}
Point *operator->() { return p; } //->运算符重载通常返回指针
private:
Point *p;
};
Point::Point() : Point(0, 0) {}
Point::Point(int x, int y) : x(x), y(y) {}
int Point::operator[](string s) {
if (s == "x") return x;
if (s == "y") return y;
return 0;
}
Point &Point::operator+=(int n) {
x += n, y += n;
return *this;
}
//类内重载+
Point Point::operator+(const Point &a) {
cout << "inner operator+" << endl;
Point c(x + a.x, y + a.y);
return c;
}
//类外重载+
Point operator+(const Point &a, const Point &b) {
cout << "outer operator+" << endl;
Point c(a.x + b.x, a.y + b.y);
return c;
}
ostream &operator<<(ostream &out, const Point &p) {
out << "(" << p.x << ", " << p.y << ")";
return out;
}
int main() {
Point a(3, 4);
Point b(7, 9);
cout << a["x"] << endl;
cout << a["y"] << endl;
Point c = a + b;
cout << a << endl;
cout << b << endl;
cout << c << endl;
a += 2; //给a的x和y各+2
cout << a << endl;
PPoint p = &a; //调用了转换构造函数
cout << p->getX() << " " << p->getY() << endl;
return 0;
}
对象 p
表现得像个指针,但是本质上是个对象,所以叫做对象指针。
4.9 实现智能指针对象
智能指针前导知识
智能指针shared_ptr
定义在头文件<memory>
中。
产生了内存泄漏的代码:
#include <iostream>
#include <memory>
using namespace std;
class A {
public :
A() {
cout << "default constructor" << endl;
}
~A() {
cout << "destructor" << endl;
}
};
int main() {
A *p1 = new A();
p1 = nullptr;
return 0;
}
因为对象 p1
没有被销毁,系统中任何一个存储数据的地方都不知道对象的地址是什么,即一片存储区是属于当前进程的,但是当前进程永远找不到这片存储区在哪儿。
使用普通指针,只有构造的过程,没有析构的过程,所以发生了内存泄漏。
但是使用智能指针,不会产生内存泄漏:
#include <iostream>
#include <memory>
using namespace std;
class A {
public :
A() {
cout << "default constructor" << endl;
}
~A() {
cout << "destructor" << endl;
}
};
int main() {
A *p1 = new A();
p1 = nullptr;
//p2就是智能指针对象
shared_ptr<A> p2(new A());
p2 = nullptr; //自动析构
return 0;
}
运行结果:
default constructor
default constructor
destructor
智能指针的智能之处:没有指针指向当前对象时,智能指针会将相关对象析构。
智能指针的原理:内部有个 引用计数,会记录指向当前对象的智能指针的数量。
#include <iostream>
#include <memory>
using namespace std;
class A {
public :
A() {
cout << "default constructor" << endl;
}
~A() {
cout << "destructor" << endl;
}
};
int main() {
A *p1 = new A();
p1 = nullptr;
//p2就是智能指针对象
shared_ptr<A> p2(new A());
//输出引用计数:p2所指向的对象有多少个指针指向它
cout << p2.use_count() << endl; // 1,只有p2
shared_ptr<A> p3 = p2;
cout << p2.use_count() << endl; // 2,p2和p3
p2 = nullptr; //自动析构
cout << p3.use_count() << endl; // 1,只有p3
return 0;
}
运行结果:
default constructor
default constructor
1
2
1
destructor
之所以最后调用 destructor
,是因为在 main
函数执行完毕后,p3
对象被自动回收,指向当前对象的智能指针的数量就变成了0,引用计数变为了0,这时候对象就被智能指针析构了。
智能指针之所以表现得像个指针,是因为它重载了 ->
运算符,还重载了 *
运算符:
#include <iostream>
#include <memory>
using namespace std;
class A {
public :
A() {
cout << "default constructor" << endl;
}
int x, y;
~A() {
cout << "destructor" << endl;
}
};
int main() {
A *p1 = new A();
p1 = nullptr;
//p2就是智能指针对象
shared_ptr<A> p2(new A());
//输出引用计数:p2所指向的对象有多少个指针指向它
cout << p2.use_count() << endl; // 1
shared_ptr<A> p3 = p2;
p2->x = 123;
p2->y = 456;
(*p2).x = 456;
cout << p2.use_count() << endl; // 2
p2 = nullptr; //自动析构
cout << p3.use_count() << endl; // 1
return 0;
}
实现智能指针对象
#include <iostream>
#include <memory>
using namespace std;
namespace haizei {
class A {
public :
A() {
cout << "default constructor" << endl;
}
int x, y;
~A() {
cout << "destructor" << endl;
}
};
class shared_ptr {
public :
shared_ptr();
shared_ptr(A *);
shared_ptr(const shared_ptr &);
int use_count();
A *operator->();
A &operator*();
//赋值运算符之所以要返回当前对象的引用,是为了支持连等的操作
shared_ptr &operator=(const shared_ptr &);
~shared_ptr();
private :
int *cnt; //引用计数
A *obj;
};
shared_ptr::shared_ptr() : obj(nullptr), cnt(nullptr) {}
shared_ptr::shared_ptr(A *obj) : obj(obj), cnt(new int(1)) {}
shared_ptr::shared_ptr(const shared_ptr &p) : obj(p.obj), cnt(p.cnt) { *p.cnt += 1; }
int shared_ptr::use_count() { return cnt ? *cnt : 0; }
A *shared_ptr::operator->() { return obj; }
A &shared_ptr::operator*() { return *obj; }
shared_ptr::~shared_ptr() {
if (cnt != nullptr) {
*cnt -= 1;
if (*cnt == 0) {
delete obj;
delete cnt;
}
obj = nullptr;
cnt = nullptr;
}
}
shared_ptr &shared_ptr::operator=(const shared_ptr &p) {
//判断是否指向同一个对象
if (this->obj != p.obj) {
if (this->cnt != nullptr) {
*(this->cnt) -= 1;
if (*(this->cnt) == 0) {
delete this->obj;
delete this->cnt;
}
}
this->obj = p.obj;
this->cnt = p.cnt;
if (this->cnt != nullptr) {
*(this->cnt) += 1;
}
}
return *this;
}
} // end of haizei
int main() {
haizei::A *p1 = new haizei::A();
p1 = nullptr;
//p2就是智能指针对象
haizei::shared_ptr p2(new haizei::A());
cout << p2.use_count() << endl; // 1
haizei::shared_ptr p3 = p2;
p2->x = 123; p2->y = 456;
(*p2).x = 456;
cout << p2.use_count() << endl; // 2
p2 = nullptr; //自动析构
cout << p3.use_count() << endl; // 1
p2 = p3;
cout << p2.use_count() << endl; // 2
return 0;
}
operator=
函数的实现比较垃圾,所以更改为如下:
#include <iostream>
#include <memory>
using namespace std;
namespace haizei {
class A {
public :
A() {
cout << "default constructor" << endl;
}
int x, y;
~A() {
cout << "destructor" << endl;
}
};
class shared_ptr {
public :
shared_ptr();
shared_ptr(A *);
shared_ptr(const shared_ptr &);
int use_count();
A *operator->();
A &operator*();
//赋值运算符之所以要返回当前对象的引用,是为了支持连等的操作
shared_ptr &operator=(const shared_ptr &);
~shared_ptr();
private :
void decrease_by_one();
void increase_by_one();
int *cnt; //引用计数
A *obj;
};
shared_ptr::shared_ptr() : obj(nullptr), cnt(nullptr) {}
shared_ptr::shared_ptr(A *obj) : obj(obj), cnt(new int(1)) {}
shared_ptr::shared_ptr(const shared_ptr &p) : obj(p.obj), cnt(p.cnt) { increase_by_one(); }
int shared_ptr::use_count() { return cnt ? *cnt : 0; }
A *shared_ptr::operator->() { return obj; }
A &shared_ptr::operator*() { return *obj; }
void shared_ptr::decrease_by_one() {
if (this->cnt != nullptr) {
*(this->cnt) -= 1;
if (*(this->cnt) == 0) {
delete this->obj;
delete this->cnt;
}
}
return ;
}
void shared_ptr::increase_by_one() {
if (cnt != nullptr) {
*cnt += 1; //cnt[0] += 1;
}
return ;
}
shared_ptr::~shared_ptr() {
this->decrease_by_one();
this->obj = nullptr;
this->cnt = nullptr;
}
shared_ptr &shared_ptr::operator=(const shared_ptr &p) {
//判断是否指向同一个对象
if (this->obj != p.obj) {
decrease_by_one(); //引用计数-1
//拷贝对象
obj = p.obj;
cnt = p.cnt;
increase_by_one(); //给新的引用计数+1
}
return *this;
}
} // end of haizei
int main() {
haizei::A *p1 = new haizei::A();
p1 = nullptr;
//p2就是智能指针对象
haizei::shared_ptr p2(new haizei::A());
cout << p2.use_count() << endl; // 1
haizei::shared_ptr p3 = p2;
p2->x = 123; p2->y = 456;
(*p2).x = 456;
cout << p2.use_count() << endl; // 2
p2 = nullptr; //自动析构
cout << p3.use_count() << endl; // 1
p2 = p3;
cout << p2.use_count() << endl; // 2
return 0;
}
运行结果:
default constructor
default constructor
1
2
1
2
destructor
至此,完成了简单的智能指针的实现。
4.10 调用对象
对数组进行排序:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
ostream &operator<<(ostream &out, const vector<int> &a) {
for (auto x : a) {
out << x << " ";
}
return out;
}
int main() {
vector<int> arr;
int n;
cin >> n;
while (n--) { int a; cin >> a, arr.push_back(a); }
sort(arr.begin(), arr.end());
cout << arr << endl;
return 0;
}
sort
函数默认是从小到大排序。如果想从大到小排序,一般是添加自定义一个比较函数:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
ostream &operator<<(ostream &out, const vector<int> &a) {
for (auto x : a) {
out << x << " ";
}
return out;
}
bool cmp1(int a, int b) {
return a > b; //当a > b的时候,a排在b前面,也就是从大到小排序
}
int main() {
vector<int> arr;
int n;
cin >> n;
while (n--) { int a; cin >> a, arr.push_back(a); }
sort(arr.begin(), arr.end(), cmp1);
cout << arr << endl;
return 0;
}
在学习了 仿函数 后,也可以使用 仿函数 来实现自定义比较规则:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
ostream &operator<<(ostream &out, const vector<int> &a) {
for (auto x : a) {
out << x << " ";
}
return out;
}
bool cmp1(int a, int b) {
return a > b; //当a > b的时候,a排在b前面,也就是从大到小排序
}
class CMP {
public :
bool operator()(int a, int b) {
return a > b;
}
};
int main() {
vector<int> arr;
int n;
cin >> n;
while (n--) { int a; cin >> a, arr.push_back(a); }
//sort(arr.begin(), arr.end(), cmp1);
sort(arr.begin(), arr.end(), CMP());//CMP()构造函数构造了一个匿名对象,第三个位置放置的应该是函数名,而仿函数的函数名就是对象名
cout << arr << endl;
return 0;
}
仿函数的功能是由重载的()运算符来决定的。
上面还可以改写为如下:
CMP cmp2;
sort(arr.begin(), arr.end(), cmp2);
仿函数比普通函数的功能更强大:根据z
值的不同,使用不同的比较规则
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
ostream &operator<<(ostream &out, const vector<int> &a) {
for (auto x : a) {
out << x << " ";
}
return out;
}
bool cmp1(int a, int b) {
return a > b; //当a > b的时候,a排在b前面,也就是从大到小排序
}
class CMP {
public :
CMP(int z = 0) : z(z) {} //z = 0 less, z = 1 greater
bool operator()(int a, int b) {
return (a < b) ^ !!(z);
}
int z;
};
int main() {
vector<int> arr;
int n;
cin >> n;
while (n--) { int a; cin >> a, arr.push_back(a); }
sort(arr.begin(), arr.end(), CMP());//CMP()就是一个匿名对象,第三个位置放置的应该是函数名,而仿函数的函数名就是对象名
cout << arr << endl;
return 0;
}
sort(arr.begin(), arr.end(), CMP());
的是默认的情况,是从小到大排序;而sort(arr.begin(), arr.end(), CMP(1));
就是从大到小排。
4.11 实现自己的 sort 函数
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
ostream &operator<<(ostream &out, const vector<int> &a) {
for (auto x : a) {
out << x << " ";
}
return out;
}
bool cmp1(int a, int b) {
return a > b; //当a > b的时候,a排在b前面,也就是从大到小排序
}
namespace haizei {
class CMP {
public :
CMP(int z = 0) : z(z) {} //z = 0 less, z = 1 greater
bool operator()(int a, int b) {
return (a < b) ^ !!(z);
}
int z;
};
//cmp是一个函数指针对象,本质是对象,表现得像个函数指针,返回值是bool,传入参数是两个int
void sort(int *arr, int l, int r, function<bool(int, int)> cmp = CMP()) {
//就是快速排序
if (l >= r) return ;
int x = l, y = r, z = arr[(l + r) >> 1];
do {
while (cmp(arr[x], z)) ++x;
while (cmp(z, arr[y])) --y;
if (x <= y) {
swap(arr[x], arr[y]);
++x, --y;
}
} while (x <= y);
sort(arr, l, y, cmp);
sort(arr, x, r, cmp);
return ;
}
}; //end of haizei
int main() {
vector<int> arr;
int n;
cin >> n;
while (n--) { int a; cin >> a, arr.push_back(a); }
//sort(arr.begin(), arr.end(), cmp1);
sort(arr.begin(), arr.end(), haizei::CMP());//CMP()就是一个匿名对象,第三个位置放置的应该是函数名,而仿函数的函数名就是对象名
cout << arr << endl;
// ====使用自己写的sort函数
int arr2[5] = {6, 8, 4, 5, 1};
haizei::sort(arr2, 0, 4); //默认情况从小到大排
for (int i = 0; i < 5; i++) {
cout << arr2[i] << " ";
}
cout << endl;
//从大到小排: 使用自定义函数
haizei::sort(arr2, 0, 4, cmp1);
for (int i = 0; i < 5; i++) {
cout << arr2[i] << " ";
}
cout << endl;
haizei::sort(arr2, 0, 4); //默认情况从小到大排
for (int i = 0; i < 5; i++) {
cout << arr2[i] << " ";
}
cout << endl;
//从大到小排: 使用仿函数
haizei::sort(arr2, 0, 4, haizei::CMP(1));
for (int i = 0; i < 5; i++) {
cout << arr2[i] << " ";
}
cout << endl;
return 0;
}
运行结果:
5 #输入
1 4 2 0 9 #输入
0 1 2 4 9 #输出
1 4 5 6 8 #输出
8 6 5 4 1 #输出
1 4 5 6 8 #输出
8 6 5 4 1 #输出
系统 sort
函数之所以能传入可调用对象,是因为使用了function
这个模板类。