C++: “仿函数” 与 “定置删除器”

2024-04-17 05:32
文章标签 c++ 函数 删除 定置

本文主要是介绍C++: “仿函数” 与 “定置删除器”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面:

之前在总结c++智能指针的时候提到过这么一个问题:对于shared_ptr,如果不是new出来的对象如何通过智能指针管理呢?其实shared_ptr设计了一个删除器来解决这个问题。

//仿函数的删除器template<class T>struct FreeFunc {void operator()(T* ptr){cout << "free:" << ptr << endl;free(ptr);}
};template<class T>struct DeleteArrayFunc {void operator()(T* ptr){ cout << "delete[]" << ptr << endl;delete[] ptr; }
};int main()
{FreeFunc<int> freeFunc;shared_ptr<int> sp1((int*)malloc(4), freeFunc);DeleteArrayFunc<int> deleteArrayFunc;shared_ptr<int> sp2((int*)malloc(4), deleteArrayFunc);return 0;

1.认识仿函数

先来看仿函数的通俗定义:仿函数(functor)又称为函数对象(function object)是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样,不过作为仿函数的类,都必须重载operator()运算符,举个例子:

class Func{public:void operator() (const string& str) const {cout<<str<<endl;}
};int main(){Func myFunc;myFunc("helloworld!");}
//运行结果    >>>helloworld!

2.定置删除器

简单的实现一个有定置删除器的shared_ptr

struct Fclose
{void operator()(void *ptr){fclose((FILE *)ptr);cout << "fclose()" << endl;}
};struct Free
{void operator()(void *ptr){free(ptr);cout << "free()" <<endl;}
};//默认删除器是delete
struct DefaultDel
{void operator()(void* ptr){delete ptr;cout << "delete ptr" << endl;}
};
template<typename T, typename D = DefaultDel>
class SharedPtr          //采用引用计数,实现一个可以有多个指针//指向同一块内存的类模板,SharedPtr是类模板,不是智能指针类型
{
public:SharedPtr(T* ptr, D del = DefaultDel());SharedPtr(const SharedPtr<T,D>& sp);SharedPtr<T,D>& operator=(SharedPtr<T,D> sp);T& operator*();T* operator->();~SharedPtr();int Count(){return *_pCount;}
private:void Release(){if (--(*_pCount) == 0){_del(_ptr);delete _pCount;_ptr = NULL;_pCount = NULL;}}
private:T* _ptr;int* _pCount;D _del;
};
//构造函数
template<typename T, typename D = DefaultDel>
SharedPtr<T,D>::SharedPtr(T* ptr,D del)
:_ptr(ptr)
, _pCount(new int(1))
,_del(del){}{}//拷贝构造函数
template<typename T, typename D = DefaultDel>
SharedPtr<T,D>::SharedPtr(const SharedPtr<T,D>& sp)
{_ptr = sp._ptr;_pCount= sp._pCount;++(*_pCount);
}//operator=	
template<typename T, typename D = DefaultDel>
SharedPtr<T,D>& SharedPtr<T,D>::operator=(SharedPtr<T,D> sp)
{std::swap(sp._ptr,_ptr);std::swap(sp._pCount,_pCount);return *this;
}//operator *
template<typename T, typename D = DefaultDel>
T& SharedPtr<T,D>::operator*()
{return *_ptr;
}//operator ->
template<typename T, typename D = DefaultDel>
T* SharedPtr<T,D>::operator->()
{return _ptr;
}//析构函数
template<typename T, typename D = DefaultDel>
SharedPtr<T,D>::~SharedPtr()
{Release();
}//测试用例
void test()
{SharedPtr<int> sp(new int(1));SharedPtr<FILE,Fclose> sp1(fopen("test.txt","w"),Fclose());SharedPtr<string,Free> sp3((string *)malloc(sizeof(string)),Free());
}int main()
{test();system("pause");return 0;}

这篇关于C++: “仿函数” 与 “定置删除器”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/910907

相关文章

MyBatis-Plus逻辑删除实现过程

《MyBatis-Plus逻辑删除实现过程》本文介绍了MyBatis-Plus如何实现逻辑删除功能,包括自动填充字段、配置与实现步骤、常见应用场景,并展示了如何使用remove方法进行逻辑删除,逻辑删... 目录1. 逻辑删除的必要性编程1.1 逻辑删除的定义1.2 逻辑删php除的优点1.3 适用场景2.

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

C++打印 vector的几种方法小结

《C++打印vector的几种方法小结》本文介绍了C++中遍历vector的几种方法,包括使用迭代器、auto关键字、typedef、计数器以及C++11引入的范围基础循环,具有一定的参考价值,感兴... 目录1. 使用迭代器2. 使用 auto (C++11) / typedef / type alias

C++ scoped_ptr 和 unique_ptr对比分析

《C++scoped_ptr和unique_ptr对比分析》本文介绍了C++中的`scoped_ptr`和`unique_ptr`,详细比较了它们的特性、使用场景以及现代C++推荐的使用`uni... 目录1. scoped_ptr基本特性主要特点2. unique_ptr基本用法3. 主要区别对比4. u

C++11中的包装器实战案例

《C++11中的包装器实战案例》本文给大家介绍C++11中的包装器实战案例,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录引言1.std::function1.1.什么是std::function1.2.核心用法1.2.1.包装普通函数1.2.

C++多线程开发环境配置方法

《C++多线程开发环境配置方法》文章详细介绍了如何在Windows上安装MinGW-w64和VSCode,并配置环境变量和编译任务,使用VSCode创建一个C++多线程测试项目,并通过配置tasks.... 目录下载安装 MinGW-w64下载安装VS code创建测试项目配置编译任务创建 tasks.js

pandas使用apply函数给表格同时添加多列

《pandas使用apply函数给表格同时添加多列》本文介绍了利用Pandas的apply函数在DataFrame中同时添加多列,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录一、Pandas使用apply函数给表格同时添加多列二、应用示例一、Pandas使用apply函