请设计一个类,不能被拷贝
拷贝只会通过拷贝构造函数和赋值运算符重载来实现,所以只需要让该类无法调用这两样东西即可
class CopyBan
{
public:
private:
/*
c++98写法,私有化后外界就无法调用
CopyBan(const CopyBan&);
CopyBan& operator=(const CopyBan&);
*/
//c++11写法
CopyBan(const CopyBan&) = delete;
CopyBan& operator=(const CopyBan&) = delete;
};
请设计一个类,不能被继承
要想让一个类不能被继承,则只需要让子类无法调用他的构造函数即可
class NonInherit
{
public:
static NonInherit CreateObject()
{
return NonInherit();
}
private:
//构造函数私有化,子类无法调用构造函数,所以无法继承
NonInherit()
{}
};
在C++11中引入了关键字final,也可以直接使用final来禁止继承
class NonInherit final
{};
请设计一个类,只能在堆上创建对象
首先要做的就是将构造函数私有化,并且防拷贝,防止其他人在栈上生成对象。
接着提供一个接口,在堆中创建对象后将指向对象的指针返回。这个接口必须要是静态的,因为要调用成员函数必须要通过一个对象, 而因为我们禁用了构造函数和拷贝,无法创建对象,所以只能声明为静态函数让其通过类域来调用这个接口。
namespace lee
{
class HeapOnly
{
public:
static HeapOnly* CreateObject()
{
return new HeapOnly();
}
private:
HeapOnly()
{}
//c++11,防拷贝
HeapOnly(const HeapOnly&) = delete;
HeapOnly& operator=(const HeapOnly&) = delete;
/*
c++98写法
HeapOnly(const HeapOnly&);
HeapOnly& operator=(const HeapOnly&);
*/
};
};
请设计一个类,只能在栈上创建对象
思路同上, 直接提供一个创建对象的接口即可。
class StackOnly
{
public:
static StackOnly CreateObject()
{
return StackOnly();
}
private:
StackOnly()
{}
};
还有一种做法,就是屏蔽new,因为new在底层会调用operator new,所以只需要将他禁用即可。
但是这种方法是有缺陷的,虽然禁用了在堆上创建对象,但是还可以在静态区创建对象,所以并不是只能在栈上创建对象的类。
class StackOnly
{
public:
StackOnly()
{}
private:
void* operator new(size_t size) = delete;
void operator delete(void* p) = delete;
};
请设计一个类,只能创建一个对象
一个类只能创建一个对象,也就是单例模式。
在上一篇中介绍过单例模式的思路,这里就不赘述了
设计模式 单例模式 :懒汉、饿汉模式实现线程安全的单例模式(C++)
饿汉模式
class EagerSingleton
{
public:
//提供给外界一个唯一的对象
static EagerSingleton* GetInstance()
{
return &_inst;
}
EagerSingleton& operator=(const EagerSingleton&) = delete; //c++11写法,为了防止拷贝,直接把拷贝构造和赋值运算符删除
EagerSingleton(const EagerSingleton&) = delete;
private:
//构造函数私有化,此时只能创建静态对象。
EagerSingleton()
{};
/*
c++98写法,将成员函数私有化,使得外界无法调用
EagerSingleton& operator=(const EagerSingleton&);
EagerSingleton(const EagerSingleton&);
*/
static EagerSingleton _inst;
//使用静态的成员,因为静态成员属于整个类域,是唯一的一份。在程序开始阶段创建之后,其他人获取时只需要返回指向这个对象的指针即可
};
EagerSingleton EagerSingleton::_inst; //程序启动时则创建对象
懒汉模式
class LazySingleton
{
public:
//获取对象
static LazySingleton* GetInstance()
{
//双重检查,第一重检验是否创建对象,防止不必要的加锁
if (_inst == nullptr)
{
//第二重检验保证线程安全
//_mtx.lock();
std::unique_lock<std::mutex> lock(_mtx);//RAII保证因异常抛出导致的安全问题
if (_inst == nullptr)
{
_inst = new LazySingleton;
}
//_mtx.unlock();
}
return _inst;
}
//删除对象
static void DelInstance()
{
std::unique_lock<std::mutex> lock(_mtx);
delete _inst;
_inst = nullptr;
}
//运用RAII的思想内嵌一个GC类,程序结束时自动调用析构函数来释放单例对象
class GC
{
public:
~GC()
{
LazySingleton::DelInstance();
}
};
static GC gc;
LazySingleton& operator=(const LazySingleton&) = delete; //c++11写法,为了防止拷贝,直接把拷贝构造和赋值运算符删除
LazySingleton(const LazySingleton&) = delete;
private:
LazySingleton()
{};
/*
c++98写法,将成员函数私有化,使得外界无法调用
LazySingleton& operator=(const LazySingleton&);
LazySingleton(const LazySingleton&);
*/
static LazySingleton* _inst;
static std::mutex _mtx;
};
LazySingleton::GC gc;
LazySingleton* LazySingleton::_inst = nullptr;
std::mutex LazySingleton::_mtx;