波奇C++11:智能指针(三)特殊类的设计和单例模式

智能指针除了创建普通对象还有以下用法

std::shared_ptr<Test> sp1(new Test[2]); // 数组
std::shared_ptr<Test> sp2((Test*)malloc(sizeof(Test))); //malloc开辟空间
std::shared_ptr<FILE> sp3(fopen("源.cpp", "r")); // 文件管理

此时原本的析构的函数可能无法发挥作用。 

~SharedPtr()
	{
		if (--(*_pcount) == 0)
		{
			
			cout << "delete pointer" << _ptr << endl;
			delete _ptr;
			delete _pcount;
		}
		else
		{
			cout << *_pcount << endl;
		}
	}

C++支持shared_ptr 定制删除器,即手动传递构造函数。

template<class T>
struct DeleteArray
{
	void operator()(T* ptr)
	{
		delete[] ptr;
	}
};
std::shared_ptr<Test> sp1(new Test[2],DeleteArray<Test>());
std::shared_ptr<Test> sp2((Test*)malloc(sizeof(Test)), [](Test* sp) {free(sp); });
std::shared_ptr<FILE> sp3(fopen("源.cpp", "r"), [](FILE* sp) {fclose(sp); });

 用function<void(T*)> 来接收可调用对象类型。

template<class T>
class SharedPtr
{
public:
    //添加模板类型,接收可调用对象
	template<class D>
	SharedPtr(T* ptr,D del)
		:_ptr(ptr)
		,_pcount(new int(1))
		,_del(del)
	{}
	~SharedPtr()
	{
		if (--(*_pcount) == 0)
		{
			
			cout << "delete pointer" << _ptr << endl;
			_del(_ptr); //调用
				delete _pcount;
		}
		else
		{
			cout << *_pcount << endl;
		}
	}
//.......
private:

	T* _ptr;
	int* _pcount;
    // 不能直接用D定义类型,用function来接收可调用对象
	function<void(T*)> _del=[](T* ptr){delete ptr;};
};

 特殊类的设计

不能被拷贝的类

class CopyBan
{
    // ...
    CopyBan(const CopyBan&)=delete;
    CopyBan& operator=(const CopyBan&)=delete;
    //...
};

只能在堆上创建

class HeapOnly    
{     
public:     
    static HeapOnly* CreateObject()  
   {      
        return new HeapOnly;    
   }
private:    
    HeapOnly() {}
    // C++11   防止 HeapOnly hp(*hptr);
    HeapOnly(const HeapOnly& hp) = delete;
    HeapOnly& operator()(const HeapOnly& hp)=delete;
};

只能在栈上创建的对象

class StackOnly
{
public:
 static StackOnly CreateObj()
 {
     return StackOnly();
 }
    
 // 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
 // StackOnly obj = StackOnly::CreateObj();
 // StackOnly* ptr3 = new StackOnly(obj); //调用拷贝构造
 void* operator new(size_t size) = delete;
 void operator delete(void* p) = delete;
private:
 StackOnly()  
 :_a(0)
 {}
 int _a;
};

不能被继承的类

class A  final
{
    // ....
};

单例模式:全局只能创建一个对象

1.构造函数私有化

2.防止拷贝

3.提供获取单例的接口和其他函数 

饿汉模式 

class Singleton
{
public:
	//获取单例对象的接口
	static Singleton& GetInstance()
	{
		return _sinst;
	}
	void test()
	{
		cout << 1;
	}
private:
	// 构造函数私有
	Singleton(){}
	// 防止拷贝
	Singleton(const Singleton& s) = delete;
	Singleton& operator()(const Singleton& s) = delete;
	map<string, string> _dict;
	static Singleton _sinst; //唯一的单例定义在类部
};
Singleton Singleton::_sinst;
int main()
{
    // 调用
	Singleton::GetInstance().test();
	return 0;
}

上面饿汉模式:在main函数之前创建单例对象

存在问题:单例对象初始化内容多,影响启动速度。两个单例类有依赖关系

 懒汉模式:在main函数后创建对象

class Singleton
{
public:
	//获取单例对象的接口
	static Singleton& GetInstance()
	{
        //第一次调用时才创建对象
		if(!_psinst)
        {
            _psinst=new Singleton;
        }
        return *_psinst;
	}
    
	void test()
	{
		cout << 1;
	}
private:
	// 构造函数私有
	Singleton(){}
	// 防止拷贝
	Singleton(const Singleton& s) = delete;
	Singleton& operator()(const Singleton& s) = delete;
	map<string, string> _dict;
	static Singleton* _psinst; //唯一的单例定义在类部
};
Singleton* Singleton::_psinst=nullptr;

单例显性释放

static void DelInstance()
    {
        if(_psinst)
        {
            delete _psinst;
            _psinst=nullptr;
        }
    }

 

相关推荐

  1. C++特殊设计模式

    2023-12-05 17:02:04       29 阅读
  2. C++】特殊设计模式

    2023-12-05 17:02:04       36 阅读
  3. [C++][特殊设计][模式]详细讲解

    2023-12-05 17:02:04       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-05 17:02:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-05 17:02:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-05 17:02:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-05 17:02:04       18 阅读

热门阅读

  1. mySql笔记

    2023-12-05 17:02:04       41 阅读
  2. Android : ViewModel_解决textView 横竖屏数据丢失

    2023-12-05 17:02:04       36 阅读
  3. 【Android】Window和WindowManager

    2023-12-05 17:02:04       41 阅读
  4. 好用的chatgpt工具用过这个比较快

    2023-12-05 17:02:04       43 阅读
  5. 【Android】布局优化方案

    2023-12-05 17:02:04       35 阅读
  6. 微前端个人理解与简单总结

    2023-12-05 17:02:04       35 阅读
  7. macOS 获取文件夹大小

    2023-12-05 17:02:04       36 阅读
  8. Stable Diffusion WebUI常用Tag收集

    2023-12-05 17:02:04       30 阅读
  9. 破解app思路

    2023-12-05 17:02:04       30 阅读
  10. 6-HBase分布式数据库

    2023-12-05 17:02:04       30 阅读
  11. vue3 子父组件、组件传值、

    2023-12-05 17:02:04       34 阅读