0

0

C++ 构造函数可以是私有的吗 C++单例模式与工厂模式基础【设计】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-30 14:56:02

|

981人浏览过

|

来源于php中文网

原创

可以,私有构造函数在单例和工厂模式中必须或常用,用于禁止外部直接实例化、控制对象创建权,类内静态函数或友元可调用,影响继承与移动语义。

c++ 构造函数可以是私有的吗 c++单例模式与工厂模式基础【设计】

构造函数可以是私有的吗

可以,而且在特定设计模式中必须是私有的。C++ 允许将构造函数声明为 privateprotectedpublic,访问控制和其他成员函数一致。

私有构造函数的核心作用是:禁止外部代码直接调用 new上实例化,把对象创建权收归类内部或友元。这不是语法糖,而是编译期强制约束。

  • 类外写 MyClass obj;new MyClass() 会触发编译错误error: 'MyClass::MyClass()' is private
  • 类内静态成员函数(如 getInstance())仍可调用私有构造函数
  • 友元函数或友元类也能调用私有构造函数——这是单例中允许测试框架注入的常见做法
  • 继承时若基类构造函数私有,派生类无法构造,除非基类显式授予友元权限

单例模式为何依赖私有构造函数

单例的本质不是“只生成一个对象”,而是“全局唯一且可控的实例入口”。私有构造函数是实现该约束的最小必要条件。

典型实现中,getInstance() 是唯一合法出口,它内部负责判断是否已存在实例,并在首次调用时通过私有构造函数初始化:

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

WPS AI
WPS AI

金山办公发布的AI办公应用,提供智能文档写作、阅读理解和问答、智能人机交互的能力。

下载
class Singleton {
private:
    static Singleton* instance;
    Singleton() = default; // 私有,禁止外部构造
public:
    static Singleton* getInstance() {
        if (!instance) instance = new Singleton(); // OK:类内可访问
        return instance;
    }
};
  • 不加 private,用户随时能绕过 getInstance() 创建新对象,单例失效
  • C++11 起推荐用局部静态变量实现线程安全单例:static Singleton& getInstance() { static Singleton inst; return inst; },仍需私有构造
  • 注意:私有构造函数 + 默认构造函数 = 无法被继承(除非用 friend 放开),这是有意为之的设计取舍

工厂模式里私有构造函数的用途差异

工厂模式不追求“唯一实例”,而追求“创建逻辑集中封装”。私有构造函数在这里的作用是防止误用,而非强制单例。

比如一个图形工厂返回不同形状,但所有形状都应由工厂统一创建,避免用户自行构造导致状态不一致或资源泄漏:

class Shape {
private:
    Shape() = default; // 禁止裸构造
protected:
    Shape(int id) : id_(id) {} // 子类可调用 protected 构造
    int id_;
};

class Circle : public Shape { Circle() : Shape(1) {} // OK };

class ShapeFactory { public: static std::unique_ptr createCircle() { return std::make_unique(); // OK:工厂可访问 protected } };

  • 此处构造函数常设为 protected 而非 private,以便子类继承并初始化
  • 工厂类本身不需要是友元;关键是把构造权限控制在可信范围内(工厂或其子类)
  • 若工厂和产品在不同模块,可能需将工厂声明为 friend class ShapeFactory;,但要谨慎——这会破坏封装边界

容易忽略的陷阱:移动语义与私有构造

C++11 后,私有构造函数还会影响移动操作。如果类禁用了拷贝但没显式定义移动构造函数,编译器可能隐式删除移动构造函数,导致 std::make_unique 或返回值优化(RVO)失败。

  • 私有默认构造函数 + 未声明移动构造函数 → 类型不可移动,某些工厂返回方式会编译不过
  • 解决方法:显式默认移动操作(若语义合理):Singleton(Singleton&&) = default;,但注意单例通常不应被移动
  • 更稳妥的做法是明确删除拷贝、默认移动(或禁止移动),并在文档中说明生命周期由类自身管理

私有构造函数看似简单,但它撬动的是整个对象生命周期的控制权。一旦放开,就很难再收回来;一旦锁死,又得提前想清楚继承、测试、序列化等延伸需求——这点比语法本身更值得花时间推演。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

297

2023.10.25

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

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

397

2023.07.18

堆和栈区别
堆和栈区别

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

575

2023.08.10

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

469

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.12.06

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

523

2023.08.10

default gateway怎么配置
default gateway怎么配置

配置default gateway的步骤:1、了解网络环境;2、获取路由器IP地址;3、登录路由器管理界面;4、找到并配置WAN口设置;5、配置默认网关;6、保存设置并退出;7、检查网络连接是否正常。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

223

2023.12.07

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

7

2026.01.30

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

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

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