智能指针除了创建普通对象还有以下用法
cpp
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")); // 文件管理
此时原本的析构的函数可能无法发挥作用。
cpp
~SharedPtr()
{
if (--(*_pcount) == 0)
{
cout << "delete pointer" << _ptr << endl;
delete _ptr;
delete _pcount;
}
else
{
cout << *_pcount << endl;
}
}
C++支持shared_ptr 定制删除器,即手动传递构造函数。
cpp
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*)> 来接收可调用对象类型。
cpp
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;};
};
特殊类的设计
不能被拷贝的类
cpp
class CopyBan
{
// ...
CopyBan(const CopyBan&)=delete;
CopyBan& operator=(const CopyBan&)=delete;
//...
};
只能在堆上创建
cpp
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;
};
只能在栈上创建的对象
cpp
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;
};
不能被继承的类
cpp
class A final
{
// ....
};
单例模式:全局只能创建一个对象
1.构造函数私有化
2.防止拷贝
3.提供获取单例的接口和其他函数
饿汉模式
cpp
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函数后创建对象
cpp
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;
单例显性释放
cpp
static void DelInstance()
{
if(_psinst)
{
delete _psinst;
_psinst=nullptr;
}
}