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

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

前面讨论的 President 类很不错,但存在一个缺陷:无法禁止通过实例化多个对象来创建多名总统:

President One, Two, Three;

由于复制构造函数是私有的,其中每个对象都是不可复制的,但您的目标是确保 President 类有且只有一个化身,即有了一个 President 对象后,就禁止创建其他的 President 对象。要实现这种功能强大的模式,可使用单例的概念,它使用私有构造函数、私有赋值运算符和静态实例成员。

提示:

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

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

cpp 复制代码
#include <iostream>
#include <string>
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;
}

输出:

The name of the President is: Abraham Lincoln

分析:

第 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++后台高级服务器课程

相关推荐
JANGHIGH1 小时前
c++ std::list使用笔记
c++·笔记·list
画个逗号给明天"1 小时前
C++STL容器之list
开发语言·c++
Lqingyyyy2 小时前
P2865 [USACO06NOV] Roadblocks G 与最短路的路径可重复的严格次短路
开发语言·c++·算法
C语言小火车3 小时前
深入解析C++26 Execution Domain:设计原理与实战应用
java·开发语言·c++·异构计算调度·c++26执行模型·domain定制
ox00804 小时前
C++ 设计模式-中介者模式
c++·设计模式·中介者模式
黄铎彦4 小时前
使用GDI+、文件和目录和打印API,批量将图片按文件名分组打包成PDF
c++·windows·pdf
Ciderw4 小时前
LLVM编译器简介
c++·golang·编译·编译器·gcc·llvm·基础设施
和光同尘@4 小时前
74. 搜索二维矩阵(LeetCode 热题 100)
数据结构·c++·线性代数·算法·leetcode·职场和发展·矩阵
无人等人4 小时前
CyberRT(apollo) IPC(shm)通信包重复/丢包 bug 及解决方案
c++·bug
Flower#4 小时前
【模板】图论 最短路 (Floyd+SPFA+Dijkstra)
c++·图论