1.设计一个类,不能被拷贝
拷贝一般只会发生在两个场景中:拷贝构造函数及赋值运算符重载。
常见类型: 线程,unique_str
如何设计?
方法1:在函数声明后,加上delete,就相当于默认删除了这两个函数。
class A
{
public:
A(const A&) = delete;
A& operator=(const A&) =delete;
};
方法2:将函数进行私有化
class A
{
private:
A(const A&);
A& operator=(const A&);
};
2.设计一个类,只能在堆上创建对象
实现方法:
步骤1.将构造函数私有化,拷贝构造函数的声明私有化,防止在拷贝的时候,在栈上创建对象。
步骤2.定义一个创建对象的静态成员函数,返回值为该类指针
class HeapOnly
{
public:
static HeapOnly* CreateObject()
//static的作用在于 扩大了这个函数的生命周期,使这个函数在对象未创建的时候,便可以使用
{
return new HeapOnly;
}
private:
HeapOnly() {}
// 1.只声明,不实现。因为实现可能会很麻烦,而你本身不需要
// 2.声明成私有
HeapOnly(const HeapOnly&);
HeapOnly(const HeapOnly&) = delete;
};
如果不使用static会造成什么样的情况呢?
如果不用static,那么函数CreateObject则只能通过已经创建的对象来进行使用。
而我们的目的是通过这个函数来创建对象。
那么岂不是相当于一个死循环了吗?
因此需要static来破掉这个死循环。
3. 设计一个类,只能在栈上创建对象
实现方法:同上只能在堆上创建对象,区别在于不会将拷贝构造私有化。
class StackOnly
{
public:
static StackOnly CreateObject(int a)
{
return StackOnly(a);
}
void* operator new(size_t size) = delete;
void operator delete(void* p) = delete;
private:
StackOnly(int a = 0) :_a(a)
{}
int _a;
};
4.设计一个类,不会被继承。
实现方法:
方法1:将构造函数私有化,这样的话子类无法使用到基类中的构造函数,故无法继承。
class NonInherit
{
public:
static NonInherit GetInstance()
{
return NonInherit();
}
private:
NonInherit()
{}
};
方法2:final 使用final关键字进行修饰的话,那么该类就无法被继承!
class A final
{}
单例模式:
一个类只能创建一个对象,即单例模式。
单例模式实现的两种方式:
1.饿汉模式
class Singleton
{
public:
static Singleton* GetInstance()
{
return &m_instance;
}
private:
Singleton() {};
Singleton(const Singleton& s) = delete;
Singleton operator=(Singleton s) = delete;
static Singleton m_instance; //声明
};
Singleton Singleton::m_instance;//定义 在进入程序之前就直接定义好
这里的static变量可以直接用构造函数,因为它的作用域是在整个类内。
2.懒汉模式
class Singleton
{
public:
static Singleton* GetInstance()
{
if (m_instance == nullptr)
{
// 注意这里一定要使用Double-Check的方式加锁,才能保证效率和线程安全
m_mtx.lock();
if (m_instance == nullptr)
m_instance = new Singleton();
m_mtx.unlock();
}
return m_instance;
}
//垃圾回收器
class CGarbo
{
public:
~CGarbo()
{
if (m_instance)
delete m_instance;
}
};
static CGarbo Garbo;
private:
Singleton() {};
Singleton(const Singleton& s) = delete;
Singleton operator=(const Singleton& s) = delete;
static Singleton* m_instance;
static mutex m_mtx;
};
Singleton* Singleton::m_instance;
mutex Singleton::m_mtx;
Singleton::CGarbo Garbo;