#include<algorithm>头文件中包含着sort排序函数,这个函数接受第三参数。
可以是函数名,也可以是函数指针,也可以是lamba表达式等等等。
这里主要提醒一点,不能传递成员函数名。
但可以是静态成员函数和全局函数。
成员函数中包含了this指针,而sort函数会像这个第三参数传递两个参数,所以,成员函数不行。
下面是一个模仿shared_ptr智能指针的程序,其中有一个将vector中指针排序的过程。
sort(e.begin(),e.end(),comparesize);
这里传递的就是全局函数。还有一点,要将全局函数在头文件中进行声明,不然会显示未识别标识符。
程序较长,挑重点看。
.h文件:
#ifndef PCH_H
#define PCH_H
#include<string>
#include<iostream>
using namespace std;
class like_shared_ptr {
public:
//交换函数
friend void swap(like_shared_ptr&, like_shared_ptr&);
//比较like_shared_ptr大小函数
friend bool comparesize(const like_shared_ptr&,const like_shared_ptr&);
//默认构造函数
like_shared_ptr():number(new int(0)),location(NULL){}
//接受指针的构造函数
like_shared_ptr(string* a) :location(a), number(new int(1)) {}
//拷贝构造函数
like_shared_ptr(const like_shared_ptr&);
//析构函数
~like_shared_ptr();
//赋值运算符
like_shared_ptr& operator =(like_shared_ptr);
//*运算符
string& operator *()const;
//->运算符
string* operator->()const;
private:
//计数器
int* number;
//内容的指针
string* location;
//此函数用于定义交换操作,替代标准库的swap函数
};
void swap(like_shared_ptr&, like_shared_ptr&);
bool comparesize(const like_shared_ptr&, const like_shared_ptr&);
#endif //PCH_H
/*头文件里面除非是非常简单的程序,否则不要定义函数,太乱的话,不利于自己维护和观看*/
.cpp文件:
#include "pch.h"
//拷贝赋值
like_shared_ptr& like_shared_ptr::operator =(like_shared_ptr a) {
//shared_ptr为空和唯一
if (*number == 1 || *number == 0)
{
delete number;
delete location;
}
//存在多个
else {
--*number;
}
/*location = a.location;
number = a.number;*/
swap(*this, a);
//为空的情况不需要number++
if (location != NULL)
++*number;
return *this;
}
//拷贝构造
like_shared_ptr::like_shared_ptr(const like_shared_ptr& a)
{
location = a.location;
number = a.number;
//空shared_ptr并不需加number 当然实际上加不加都不会出现问题
if (location != NULL)
++*number;
}
//析构
like_shared_ptr::~like_shared_ptr() {
//这里如果number为NULL的话,执行到这里会发生运行时错误,但是编译时报不出错误,这种错误比较严重并且难以查找
//添加上number==null就可以了,对空的指针delete没有任何动作
if (*number == 1||*number==0) {
delete number;
delete location;
}
else {
--*number;
}
}
//*运算符重载(可以时一元运算符也可以是二元运算符,根据重载函数中的参数来)
string& like_shared_ptr::operator *()const {
return *location;
}
//->运算符重载(一元运算符,只接受一个餐宿)
string* like_shared_ptr::operator ->()const {
return location;
}
/*这里参数要是引用,不然会出现没有交换而访问释放了的地址的错误,访问控制错误
实际上根据本例的的要求并不需要定义这个swap函数,仅仅是想要实验一番*/
void swap(like_shared_ptr& a,like_shared_ptr& b) {
cout << "swap" << endl;
using std::swap;
swap(b.location, a.location);
swap(b.number, a.number);
}
//比较like_shared_ptr大小函数
bool comparesize( const like_shared_ptr& a, const like_shared_ptr& b) {
cout << "comparesize" << endl;
if (*b.location > *a.location)
return true;
else
return false;
}
main函数:
#include "pch.h"
#include <iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
like_shared_ptr a;
like_shared_ptr b(new string("xiaoming"));
cout << *b << endl;
cout <<(*b).size()<< endl;
//这里调用string对象中的size()函数
cout <<b->size() << endl;
//这里调用了一次swap
a = b;
*a = "xiaowang";
cout << *a << endl;
like_shared_ptr c(b);
cout << *c << endl;
like_shared_ptr d;
//这里调用了一次swap
d = a;
cout << endl << endl << endl;
vector<like_shared_ptr> e;
e.push_back(a);
e.push_back(b);
e.push_back(c);
e.push_back(d);
//这里我们需要传递第三个参数,不然sort函数没有办法比较比较like_shared_ptr对象
//sort中调用了swap函数,因为我们定义了自己的版本,所以呢,调用自己定义的版本
sort(e.begin(), e.end(),comparesize);
//这里遍历的时候里面不能有空的like_shared_ptr,不然会发生读取错误,location为nullptr,并不能读其中内容。
for (auto a : e) {
cout << *a << endl;
}
}
/*总结:
1.运算符*和—>运算符重载:
如果返回的时对象指针的话,不需要再->来使用成员变量和成员函数,直接即可。而对于返回的时对象,则需要加.来使用
或许可以从这里看到点什么东西。
当我们用指针访问对象时,可以直接访问私有成员。
而用对象的话,并不能直接访问私有成员。或许这两者之间底层的实现方式不同哦。
这里->运算符之后好像只能接成员变量和成员函数,其他的都会报错
2.全局函数的问题,
全局变量要再头文件中进行声明,不管是不是友元函数,都是这样。
*/