zoukankan      html  css  js  c++  java
  • 单例模式

     
     
    #include <iostream>
    #include<vector>
    using namespace std;
    
    
    class Singleton
    {
    	static Singleton s;
    	int i;
    	Singleton(int x) :i(x)
    	{};
    	Singleton& operator=(Singleton&);//不允许赋值
    	Singleton(const Singleton&);//不允许拷贝
    public:
    	static Singleton& instance()//为了后面可以用引用接收,所以这里要返回引用
    	{
    		return s;
    	}
    	int getValue()
    	{
    		return i;
    	}
    	void setValue(int x)
    	{
    		i = x;
    	}
    };
    Singleton Singleton::s(47);
    int main()
    {
    	Singleton& s = Singleton::instance();//防止调用拷贝构造函数,所以这里用引用
    	cout << s.getValue() << endl;
    	cout << &s << endl;
    	Singleton& s2 = Singleton::instance();
    	//Singleton s3;不存在默认构造函数,即该类不能继续实例化
    	s2.setValue(9);
    	cout << &s2 << endl;
    	cout << s.getValue() << endl;
    	return 0;
    }
    

      运行结果:从输出结果我们可以知道,对象地址是一样的,即这都是同一个对象

    上述实现通过返回一个引用实现单例模式。如果返回的是指针而不是引用,用户可能会不小心删除此指针,因此上述实现比返回指针更安全。

    问:在上面我们把拷贝构造函数和赋值操作符都声明为私有,为什么要声明为私有?仅仅把构造函数声明为私有不久可以了吗?

    答:不可以的,如果不把拷贝构造函数声明为私有那么还是可以通过拷贝构造函数来创造一个类新的对象。

    #include <iostream>
    #include<vector>
    using namespace std;
    
    
    class Singleton
    {
    	static Singleton s;
    	int i;
    	Singleton(int x) :i(x)
    	{};
    	//Singleton& operator=(Singleton&);//不允许赋值
    	//Singleton(const Singleton&);//不允许拷贝
    public:
    	static Singleton instance()
    	{
    		return s;
    	}
    	int getValue()
    	{
    		return i;
    	}
    	void setValue(int x)
    	{
    		i = x;
    	}
    };
    Singleton Singleton::s(47);
    int main()
    {
    	Singleton s = Singleton::instance();//调用了拷贝构造函数
    	//cout << s.getValue() << endl;
    	cout << &s << endl;
    	Singleton s2 = Singleton::instance();
    	//Singleton s3;不存在默认构造函数,即该类不能继续实例化
    	//s2.setValue(9);
    	cout << &s2 << endl;
    	//cout << s.getValue() << endl;
    	return 0;
    }
    

      运行结果:

    从截图我们可以知道,这是两个不同的对象,因为我们调用了拷贝构造函数。

    从这里也可以知道,我们要做一个单实例模式时需要采用引用的方法这样才不会调用拷贝构造函数。

    此外对于赋值操作符声明为私有主要是为了证明这个类产生的对象都是同一个对象是调用了类的构造函数后的结果而不是因为其中调用了赋值操作符产生的结果。

    最简单的单实例例子:

    #include <iostream>
    #include<vector>
    using namespace std;
    
    
    class Singleton
    {
    	static Singleton a;
    	Singleton() {};
    	Singleton(Singleton&) {};
    public:
    	static Singleton& instance()
    	{
    		return a;
    	}
    };
    Singleton Singleton::a;//静态数据成员需要在类外定义
    int main()
    {
    	Singleton& temp = Singleton::instance();//这里用引用,是为了不调用拷贝构造函数
    	cout << &temp << endl;
    	Singleton &temp1 = Singleton::instance();
    	cout << &temp1 << endl;
    	return 0;
    }
    

      运行结果:

  • 相关阅读:
    做到就得到,人生成功的启示
    这个世界没什么过不去的事情,记我的经历
    要想富,先读书,没有文化要吃一辈子的亏
    git学习笔记11-git多人协作-实际多人怎么开发
    git学习笔记10-新开发的功能不想要了-强行删除分支
    git学习笔记09-bug分支-自己的分支改到一半了-要去改bug怎么办?
    git学习笔记08-分支管理策略-实际上我们应该怎么应用分支
    git学习笔记07-冲突了怎么办-那就解决冲突呗
    git学习笔记06-创建分支合并分支-比svn快多了,因为只有指针在改变
    git学习笔记05-从远程库克隆
  • 原文地址:https://www.cnblogs.com/wuyepeng/p/9697357.html
Copyright © 2011-2022 走看看