0

0

c++中如何定义私有构造函数_c++单例模式核心【干货】

穿越時空

穿越時空

发布时间:2026-02-13 05:51:14

|

878人浏览过

|

来源于php中文网

原创

私有构造函数需将构造函数、拷贝构造、移动构造及赋值运算符均声明为private或=delete;c++11起推荐统一用=delete确保编译期拦截。

c++中如何定义私有构造函数_c++单例模式核心【干货】

私有构造函数怎么写,为什么不能 public

私有构造函数就是把 Constructor 的访问权限设为 private,外部无法直接 new 或栈上实例化。这是单例的前提——禁止任意创建对象。

常见错误是只把构造函数设为 private,却忘了把拷贝构造、移动构造、赋值操作也禁掉,导致绕过单例约束:

  • private: 构造函数、拷贝构造函数、移动构造函数、operator=(含拷贝/移动赋值)都得显式声明为 deleteprivate
  • 否则别人用 A a = b;A a(std::move(b)); 就能偷偷生成新实例
  • C++11 起推荐统一用 = delete,比仅声明 private 更安全(编译期拦截)

线程安全的单例怎么实现(懒汉式)

最常用的是“双重检查锁定”(Double-Checked Locking),但 C++11 之前有内存重排序风险;C++11 及以后靠 std::call_once + std::once_flag 更简洁可靠:

class Singleton {
private:
    Singleton() = default;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    static std::unique_ptr<Singleton> instance_;
    static std::once_flag init_flag_;

public:
    static Singleton& getInstance() {
        std::call_once(init_flag_, []{
            instance_ = std::make_unique<Singleton>();
        });
        return *instance_;
    }
};

注意点:

立即学习C++免费学习笔记(深入)”;

CG Faces
CG Faces

免费的 AI 人物图像素材网站

下载
  • std::call_once 是线程安全的初始化入口,只执行一次,无需手写锁
  • std::unique_ptr 管理堆内存,避免裸指针和手动 delete
  • 不要用局部静态变量(如 static Singleton s;)实现懒汉式——它虽线程安全(C++11 要求),但销毁时机不可控,可能在其他静态对象析构后才被析构,引发 use-after-free

饿汉式单例的适用场景和隐患

饿汉式在程序启动时就构造好唯一实例,靠全局静态对象实现:

class Singleton {
private:
    Singleton() = default;
    static Singleton instance_;
public:
    static Singleton& getInstance() { return instance_; }
};

优点是绝对线程安全、无延迟;但问题也很直接:

  • 实例在 main() 之前就构造,依赖的其他全局对象可能还没初始化(静态初始化顺序问题)
  • 即使从不调用 getInstance(),也会强制构造,浪费资源
  • 无法在构造函数中做运行时参数检查或抛异常(静态对象初始化阶段异常会导致程序终止)

单例类里怎么安全持有资源(如文件句柄、网络连接)

单例生命周期贯穿整个程序,资源释放必须可控且不依赖析构时机。别指望 ~Singleton() 一定被调用(比如 exit() 或 crash)。

实操建议:

  • 资源初始化放在 getInstance() 首次调用时(懒汉),而不是构造函数里
  • 提供显式 shutdown()close() 方法,由主逻辑控制何时释放
  • 若必须自动清理,可用 atexit() 注册清理函数,但要确保该函数只执行一次且不抛异常
  • 避免在单例析构函数里做 I/O 或锁操作——此时其他静态对象可能已析构,容易死锁或崩溃

真正难的不是写出来,而是想清楚:这个“唯一实例”是否真的需要跨所有模块共享?有没有更松耦合的替代方案(比如依赖注入)?很多单例最后成了隐藏的全局状态,让测试和重构变困难。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1550

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

236

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

127

2025.10.17

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

193

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

104

2025.10.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

411

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

587

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

411

2023.07.18

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

4

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.3万人学习

C 教程
C 教程

共75课时 | 4.7万人学习

C++教程
C++教程

共115课时 | 17.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号