Article Directory
foreword
There are some special classes that require us to learn how to design alone.
Design a class that cannot be copied
It cannot be copied or sealed: copy construction, assignment overloading.
- c++ 98
class CopyBan
{
private:
CopyBan(const CopyBan& ban);
CopyBan& operator=(const CopyBan& ban);
};
- c++11
class CopyBan
{
CopyBan(const CopyBan& ban) = delete;
CopyBan& operator=(const CopyBan& ban) = delete;
};
Design a class that can only create objects on the heap
The constructor is set to private to prevent creation on the stack; copying, assignment and overloading are all banned
class HeapOnly
{
public:
static HeapOnly* GetHeapOnly()
{
return new HeapOnly;
}
private:
HeapOnly()
{
}
HeapOnly(const HeapOnly& ho) = delete;
HeapOnly& operator=(const HeapOnly& ho) = delete;
};
Design a class that can only create objects on the stack
To disable the new and delete keywords, the return value of new must be specified as void*; the parameters of delete must also be specified.
class StackOnly
{
public:
static StackOnly GetHeapOnly()
{
return StackOnly();
}
private:
StackOnly()
{
}
void* operator new(size_t size) = delete;
void operator delete(void* p) = delete;
};
Design an object that cannot be inherited
- c++98
In the inheritance system, the initialization of the subclass must adjust the constructor of the parent class , so as long as the constructor of the parent class is sealed, the design can be completed
- c++11
In C++11, adding the final keyword to a class means that the class cannot be inherited.
class NoExtend final
{
};
Design a class, only one object can be created (singleton mode)
- lazy man
The lazy man creates the object when it is used for the first time.
#include <mutex>
class Lazy
{
public:
static Lazy* GetInstance()
{
//因为只会创建一次,避免反复申请锁
//双重判断提高效率保证安全
if (_ptr == nullptr)
{
imtx.lock();
if (_ptr == nullptr)
{
_ptr = new Lazy();
}
imtx.unlock();
}
return _ptr;
}
//因为是指针,所以设计一个内部的、
//垃圾回收类
class GC
{
public:
~GC()
{
if (_ptr)
{
delete _ptr;
}
}
};
static GC gc;
private:
Lazy()
{
}
static Lazy* _ptr;
mutex vtx;//保护类内资源
static mutex imtx;//保护实例对象
};
Lazy* Lazy::_ptr = nullptr;
mutex Lazy::imtx;//不需要给值,但要在外面定义一下
- hungry man
class Starve
{
public:
static Starve* getInstance()
{
return _ptr;
}
private:
Starve()
{
}
static Starve* _ptr;
};
//在main函数之前就创建好了
Starve* Starve::_ptr = new Starve;
Advantages and disadvantages analysis:
Lazy:
Pros: There is no load on process startup; multiple singletons can control sequential startup.
Disadvantages: more troublesome to implement
Hungry man:
Advantages: Simple
Disadvantages: Slow startup; the reading order cannot be determined (multiple threads to start multiple singletons).