• C++中只能有一个实例的单例类


    C++中只能有一个实例的单例类

    前面讨论的 President 类很不错,但存在一个缺陷:无法禁止通过实例化多个对象来创建多名总统:
    President One, Two, Three;
    由于复制构造函数是私有的,其中每个对象都是不可复制的,但您的目标是确保 President 类有且只有一个化身,即有了一个 President 对象后,就禁止创建其他的 President 对象。要实现这种功能强大的模式,可使用单例的概念,它使用私有构造函数、私有赋值运算符和静态实例成员。

    提示:

    将关键字 static 用于类的数据成员时,该数据成员将在所有实例之间共享。
    将 static 用于函数中声明的局部变量时,该变量的值将在两次调用之间保持不变。
    将 static 用于成员函数(方法)时,该方法将在所有成员之间共享。
    
    • 1
    • 2
    • 3

    要创建单例类,关键字 static 必不可少,如以下示例程序所示:

    #include 
    #include 
    using namespace std;
    
    class President
    {
        private:
        President() {}; // private default constructor
        President(const President&); // private copy constructor
        const President& operator=(const President&); // assignment operator
    
        string name;
    
        public:
        static President& GetInstance()
        {
            // static objects are constructed only once
            static President onlyInstance; 
            return onlyInstance;
        }
    
        string GetName()
        { return name; }
    
        void SetName(string InputName)
        { name = InputName; }
    };
    
    int main()
    {
        President& onlyPresident = President::GetInstance();
        onlyPresident.SetName("Abraham Lincoln");
    
        // uncomment lines to see how compile failures prohibit duplicates
        // President second; // cannot access constructor
        // President* third= new President(); // cannot access constructor
        // President fourth = onlyPresident; // cannot access copy constructor
        // onlyPresident = President::GetInstance(); // cannot access operator=
    
        cout << "The name of the President is: ";
        cout << President::GetInstance().GetName() << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    输出:

    The name of the President is: Abraham Lincoln
    
    • 1

    分析:

    第 28~43 行的 main( )包含大量注释,演示了各种创建 President 实例和拷贝的方式,它们都无法
    通过编译。下面逐一进行分析。
    34: // President second; // cannot access constructor
    35: // President* third= new President(); // cannot access constructor
    第 34 和 35 行分别试图使用默认构造函数在堆和自由存储区中创建对象, 但默认构造函数不可用,因为它是私有的,如第 7 行所示。
    36: // President fourth = onlyPresident; // cannot access copy constructor
    第 36 行试图使用复制构造函数创建现有对象的拷贝(在创建对象的同时赋值将调用复制构造函数),但在 main( )中不能使用复制构造函数,因为第 8 行将其声明成了私有的。
    37: // OnlyPresident = President::GetInstance(); // cannot access operator=
    第 37 行试图通过赋值创建对象的拷贝,但行不通,因为第 9 行将赋值运算符声明成了私有的。因此, 在main( )中, 不能创建President类的实例, 唯一的方法是使用静态函数GetInstance( )来获取President的实例,如第 30 行所示。 GetInstance( )是静态成员,类似于全局函数,无需通过对象来调用它。GetInstance( )是在第 14~19 行实现的, 它使用静态变量 onlyInstance 确保有且只有一个 President 实例。
    为更好地理解这一点,可以认为第 17 行只执行一次(静态初始化),因此 GetInstance( )返回唯一一个President 实例,而不管您如何频繁地调用 President:: GetInstance( )。

    该文章会更新,欢迎大家批评指正。

    推荐一个零声学院的C++服务器开发课程,个人觉得老师讲得不错,
    分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
    fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
    TCP/IP,协程,DPDK等技术内容
    点击立即学习:C/C++后台高级服务器课程

  • 相关阅读:
    cesium加载geojso面数据拉升高度
    Arduino开发实例-DIY电能表
    java毕业设计调酒互动交流平台Mybatis+系统+数据库+调试部署
    前端例程20220728:按钮点击涟漪效果
    进程状态和优先级【Linux】
    MySQL命令(命令行方式,而非图形界面方式)
    做个清醒的程序员之拥抱AI
    刷题笔记(第三天)
    APP定制开发流程和特点有哪些?
    Django Form组件
  • 原文地址:https://blog.csdn.net/qq_41317716/article/details/134498195