[C++]特殊类的设计:单例模式

特殊类设计

不能被拷贝的类

C++经典的防拷贝有:unique_ptr thread mutex istream ostream

要想让一个类不支持拷贝,只要让它的拷贝构造函数和赋值运算符无法调用即可

  • C++98

    对拷贝构造函数和赋值运算符只声明,不定义,防止编译器自己生成。并将其访问权限设为私有,防止有人在类外定义。

    class CopyBan
    {
    	//...
    
    private:
    	CopyBan(const CopyBan&);
    	CopyBan& operator=(const CopyBan&);
    	//...
    };
    
  • C++11

    使用 delete

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

只能在堆上创建对象的类

设计思路,将构造函数设为私有,只提供专门在堆上创建对象的接口:

该接口必须设置为静态成员函数,不依赖对象调用。

class HeapOnly
{
public:
	static HeapOnly* CreateObj()
	{
		return new HeapOnly;
	}
	HeapOnly(const HeapOnly&) = delete;
private:
	HeapOnly()
	{}
};

为了防止有人在栈上使用拷贝构造,这里可以把拷贝构造删除。

只能在栈上创建对象的类

class  StackOnly
{
public:
	static StackOnly CreateObj()
	{
		return StackOnly();
	}
	StackOnly(const StackOnly&) = delete;
private:
	StackOnly()
	{}
};

不能被继承的类

  • C++98

    将构造函数私有化,派生类不能调用基类中的构造函数,则无法继承

class NonInherit
{
public:
	static NonInherit GetInstance()
	{
		return NonInherit();
	}
private:
	NonInherit()
	{}
};
  • C++11

    使用 final 关键字

class A final
{
	//...
};

单例模式

一个类只能创建出一个对象,即单例模式

  • 饿汉模式

即一开始(main 函数之前)就创建对象,后续只能通过对外提供的接口来获取对象,而不能继续创建。

如下,先把构造函数设为私有,保证无法在类外创建对象。然后在类内创建自己的对象的指针,因为获取对象的函数必须是静态的,而静态成员函数只能使用静态成员变量,所以这个指针也要设置为静态的。静态成员变量类内声明类外定义,由于在声明是类内的,所以它仍属于类内成员,所以可以调用构造函数实例化出对象。

不能忘了把拷贝构造函数删除,防止别人通过拷贝构造创建新的对象。

class Singletion
{
public:
	static Singletion* GetInstance()
	{
		return _spInst;
	}
private:
	Singletion()
	{}
	Singletion(const Singletion&) = delete;

	static Singletion* _spInst;
};

Singletion* Singletion::_spInst = new Singletion;
  • 懒汉模式

即一开始不创建对象,在第一次调用 GetInstance 时创建对象

class Singletion
{
public:
	static Singletion* GetInstance()
	{
		if (_spInst == nullptr)
		{
			_spInst = new Singletion;
		}
		return _spInst;
	}
private:
	Singletion()
	{}
	Singletion(const Singletion&) = delete;

	static Singletion* _spInst;
};

Singletion* Singletion::_spInst = nullptr;

总结:

饿汉模式特点:简单,初始化顺序不确定,如果有依赖关系就会有问题。饿汉对象初始化慢且多个饿汉单例对象会影响程序的启动

懒汉模式特点:复杂一点,初始化顺序可以控制,延迟加载初始化,不影响程序启动。

你可能感兴趣的:(C++学习,单例模式,c++,开发语言,后端)