关闭

设计模式之单例类——如何让一个类只实例化一个对象

标签: 对象实例
1369人阅读 评论(0) 收藏 举报
分类:

其实这是一道面试题。
这道题的思路是,我只让这个类通过一个公有函数实例化对象,即可以将构造函数设置为私有成员函数。

include <iostream>
using namespace std;

class Single
{
public:

    static Single& SingleCreate()
    {
        if (m == NULL)
        {
            m = new Single();
        }
            return *m;
    }
    ~Single()
    {
        delete m;
    }

    Single(const Single &a)
    {
    if (m == NULL)
    {
    m = new Single();
    }
    }

private:
    Single()
    {}
    static  Single *m;
};

Single* Single::m = NULL;

int main()
{
    Single a = Single::SingleCreate();
}

这是我第一次写出的代码,我本来认为这样就可以了,结果经过我的调试,发现这样写是有问题的。
这里写图片描述

通过上面的图片可以看出,我们实例化的a的地址,跟在SingleCreate函数中返回的m的值是不同的,即这个类实例化了两个对象,这样就偏题了。
经过分析,我们现在来看SingleCreate函数

    static Single& SingleCreate()
    {
        if (m == NULL)
        {
            m = new Single();
        }
            return *m;
    }

这里retuen 的*m,会自动生成拷贝构造函数,因为return *m是返回一个对象,这里是返回临时变量,自动调用拷贝构造函数,因为我们没有定义拷贝构造函数,所以这里会自动生成一个拷贝构造函数。
所以达不到只实例化一个对象的目的
经过上面的分析,经代码优化为


class Single
{
public:


    static Single* SingleCreatePtr()
    {
        if (m == NULL)
        {
            m = new Single();
        }
        return m;
    }
    ~Single()
    {
        delete m;
    }


private:
    Single()
    {}

    static  Single *m;
};
Single* Single::m = NULL;
int main()
{
    Single *a = Single::SingleCreatePtr();
}

这个时候经过调试,得到下面
这里写图片描述
这个时候就得到的是一个对象。因为传指针的实质是在传地址,不会产生临时变量。
现在已经解决了在返回值时只实例化一个对象的问题
接下来看第三个问题
三、构造函数
接下来我们在main函数中加这么一句话:

Single *b = a;

这个时候会发生什么呢?
对,会实例化出另一个对象,这是因为编译器自动生成了赋值构造函数,就像上面的拷贝构造函数一样,都是编译器自动生成并调用的,那么如何防止这些情况的发生?
我的方法是在类中只声明不定义拷贝构造函数以及赋值构造函数。

class Single
{
public:

    static Single& SingleCreate()
    {
        if (m == NULL)
        {
            m = new Single();
        }
            return *m;
    }
    static Single* SingleCreatePtr()
    {
        if (m == NULL)
        {
            m = new Single();
        }
        return m;
    }
    ~Single()
    {
        delete m;
    }


private:
    Single()
    {}
    Single(const Single &a);
    Single& operator = (const Single &a);
    static  Single *m;
};

即将拷贝构造函数和赋值运算符重载函数都变成私有的成员函数,在外不可调用,就避免了因为构造函数多实例化对象的情况。
四、通过静态局部变量

class Single  
{  
private:  
    Single()   //构造函数是私有的  
    {  
    }  
public:  
    static Single & GetInstance()  
    {  
        static Single instance;   //局部静态变量  
        return instance;  
    }  
};  

静态局部变量在GetInstance函数中被定义,初始化为0,且静态局部变量存放在内存的全局数据区。函数结束时,静态局部变量不会消失,每次该函数调用 时,也不会为其重新分配空间。它始终驻留在全局数据区,直到程序运行结束。静态局部变量的初始化与全局变量类似.如果不为其显式初始化,则C++自动为其 初始化为0。
静态局部变量与全局变量共享全局数据区,但静态局部变量只在定义它的函数中可见。
通过声明静态局部变量,但不进行初始化及赋值,那么编译器自动初始化为0,且永远不会改变,所以只会实例化一个对象。这个方法更加便捷高效。
但是上面的代码没有考虑类拷贝的问题,大家参照上面的类拷贝问题可以自己把函数加上,然后去试一试,有问题可以留言大家一起解决~

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

确保对象的唯一性——单例模式

什么是单例模式单例模式定义如下: 单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一...
  • Todo_
  • Todo_
  • 2016-01-26 11:11
  • 2002

工厂模式 -- 类的实例化延迟到其子类

简单工厂模式虽然简单,但存在一个很严重的问题。当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码,将违背“开闭原则”,如何实现增加新产品而不影响...
  • u013233468
  • u013233468
  • 2014-01-14 14:39
  • 1499

定义一个类让其只能实例化一个对象

一个类只实例化出一个对象称为单例模式
  • Dakuan_chen
  • Dakuan_chen
  • 2017-04-03 18:42
  • 797

用c++设计一个类,这个类只能被实例化3次,且不能被继承

// only3Instance.cpp : 定义控制台应用程序的入口点。 //通过此实例实现一个类,这个类不能被继承,并且最多可以实例化3次 //在设计模式中,有一种模式叫“单例模式”,这个模式向我...
  • dai_jing
  • dai_jing
  • 2013-09-16 15:22
  • 1192

题目2:Singelton单例模式:设计一个类,只能生成该类的一个实例。

只能生成一个实例的类是实现了Singelton(单例)模式的类型。类是通过构造函数创建实例的,所以要把构造函数设为私有函数,以禁止其他人创建实例。本文提供了几种方式:经典懒汉式、经典饿汉式、多线程式。...
  • jdx888
  • jdx888
  • 2016-09-08 12:05
  • 158

Singleton设计模式(一个类只允许一个实例)

Singleton设计模式 我们知道,Singleton设计模式要求一个类class只能有一个实例instance存在,下面用C++来实现: #include #include u...
  • ForgotAboutGirl
  • ForgotAboutGirl
  • 2011-09-16 01:03
  • 2825

设计模式_继承_类中成员_覆盖_子类的实例化过程

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------ 【设计模式】 解决某一类问题最快且有效的方法。java中23种设计模式: ...
  • gzi305366853
  • gzi305366853
  • 2013-03-13 00:01
  • 274

设计模式之登记式单例类

import java.util.HashMap;  02 public class RegSingleton  03 ...
  • zhanghw_1229
  • zhanghw_1229
  • 2011-11-14 22:35
  • 226

【设计模式】【单例类】

单例类模板的简洁创建方法
  • u010276189
  • u010276189
  • 2015-06-14 01:11
  • 287

Java设计模式--单例类

Singleton饿汉模式 public class Sigleton { //饿汉模式 outInstance是私有的 private static Sigleton ourI...
  • fjnu_se
  • fjnu_se
  • 2017-06-10 00:18
  • 66
    个人资料
    • 访问:95462次
    • 积分:1633
    • 等级:
    • 排名:千里之外
    • 原创:64篇
    • 转载:4篇
    • 译文:0篇
    • 评论:13条
    最新评论