跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 特殊类设计:拷贝控制、内存分配与单例模式

详细讲解了 C++ 中五种特殊类的设计实现,包括不可拷贝类、堆栈受限类、不可继承类及单例模式。通过对比 C++98 与 C++11 语法差异,提供了私有构造函数、静态工厂方法、operator new 重载及 final 关键字等关键技术手段。重点分析了饿汉式与懒汉式单例的实现原理、线程安全性及资源清理策略,帮助开发者构建更安全、可控的类结构。

苹果系统发布于 2026/3/24更新于 2026/8/1632 浏览
C++ 特殊类设计:拷贝控制、内存分配与单例模式

引言

在 C++ 面向对象编程中,类不仅是封装数据与行为的容器,更是控制资源生命周期的核心。除了常规业务逻辑,实际开发常面临一些特殊约束场景:防止对象拷贝以避免资源重复释放,限定对象创建位置(仅堆或仅栈)以规范内存管理,禁止类被继承以保障核心逻辑不被篡改,或是确保类仅存在一个实例以实现全局资源统一调度。这些需求的实现,正是特殊类设计的核心范畴。

本文将系统拆解五种典型特殊类的实现逻辑与技术细节,结合 C++ 语言特性提供完整代码示例,并深入分析方案的优缺点与适用场景。

设计一个不能被拷贝的类

要实现一个不可拷贝的类,核心思路是禁用拷贝构造函数和赋值运算符重载。根据 C++ 标准版本的不同,有两种主流做法。

在 C++98 时代,通常将这两个函数声明为私有且不定义,这样外部调用时会链接失败。到了 C++11,更推荐使用 = delete 显式删除默认生成的成员函数,语义更清晰且编译期报错更友好。

class NoCopy {
public:
    // C++11 推荐写法
    NoCopy(const NoCopy&) = delete;
    NoCopy& operator=(const NoCopy&) = delete;
};

设计一个只能在堆上创建对象的类

限制对象只能在堆上创建,意味着要阻止栈上的自动构造以及直接 new 之外的其他分配方式。具体策略是将构造函数设为私有,并提供一个静态工厂函数来负责堆内存的分配。

同时,为了防止拷贝导致新的对象被意外创建,必须禁用拷贝操作。

class HeapOnly {
public:
    static HeapOnly* CreateObj() {
        return new HeapOnly();
    }

private:
    HeapOnly() {}
    ~HeapOnly() {}
    
    // 禁止拷贝
    HeapOnly(const HeapOnly&) = delete;
    HeapOnly& operator=(const HeapOnly&) = delete;
};

注意,这里析构函数也建议设为私有或受保护,配合智能指针使用会更安全,但基础实现中保持私有即可。

设计一个只能在栈上创建对象的类

反过来,如果希望对象只能在栈上创建,就需要阻止 new 操作符的使用。这可以通过私有化构造函数并删除全局 operator new 来实现。

由于构造函数私有,外部无法直接实例化,因此需要提供一个静态成员函数返回对象值。这里利用返回值优化(RVO),避免不必要的拷贝。

class StackOnly {
public:
    static StackOnly CreateObj() {
        return StackOnly();
    }

private:
    StackOnly() {}
    ~StackOnly() {}
    
    // 禁止堆分配
    void* operator new(size_t) = delete;
    void* operator new[](size_t) = delete;
    
    // 禁止拷贝
    StackOnly(const StackOnly&) = delete;
    StackOnly& operator=(const StackOnly&) = delete;
};

这里删除 operator new 后,该类就无法使用 new 关键字了,因为默认会调用全局的 new。

设计一个不能被继承的类

禁止类被继承同样有两种经典方案。C++98 风格是通过将构造函数设为私有,使得派生类无法访问基类构造函数从而无法实例化。而 C++11 引入了 final 关键字,这是更现代、更直观的方式。

class FinalClass final {
    // ... 类内容
};
// class Derived : public FinalClass {}; // 编译错误

设计一个只能创建一个对象的类(单例模式)

单例模式保证系统中该类只有一个实例,并提供全局访问点。常见的实现有饿汉式和懒汉式两种。

饿汉模式

饿汉式在类加载时就初始化实例。优点是线程安全且实现简单;缺点是如果初始化开销大,会影响启动速度,且难以控制不同编译单元间的实例化顺序。

namespace hungry {
class Singleton {
public:
    static Singleton& GetInstance() {
        return _sinst;
    }

private:
    Singleton() {}
    ~Singleton() {}
    
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    
    static Singleton _sinst;
};

// 静态成员变量定义
Singleton Singleton::_sinst;
}

懒汉模式

懒汉式则延迟到第一次使用时才创建实例。为了支持线程安全,通常需要加锁,但基础版本如下所示。此外,为了在程序结束时正确清理资源,可以借助局部静态对象的析构机制。

单例模式流程图

namespace lazy {
class Singleton {
public:
    static Singleton& GetInstance() {
        if (_psinst == nullptr) {
            _psinst = new Singleton();
        }
        return *_psinst;
    }

    static void DelInstance() {
        if (_psinst) {
            delete _psinst;
            _psinst = nullptr;
        }
    }

private:
    Singleton() {}
    ~Singleton() {}
    
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    
    static Singleton* _psinst;
    
    // 辅助类,用于程序退出时销毁单例
    class tmp {
    public:
        ~tmp() {
            DelInstance();
        }
    };
    
    static tmp _tmp;
};

Singleton* Singleton::_psinst = nullptr;
Singleton::tmp Singleton::_tmp;
}

单例销毁时机

一般单例不需要手动释放,因为程序结束时操作系统会自动回收。但在特殊场景下,比如中途需要显示释放,或者程序结束时需要持久化数据,就需要调用析构函数。上述代码中的 tmp 类利用了局部静态对象的析构顺序,保证了在 main 函数结束后、程序终止前执行清理逻辑。

目录

  1. 引言
  2. 设计一个不能被拷贝的类
  3. 设计一个只能在堆上创建对象的类
  4. 设计一个只能在栈上创建对象的类
  5. 设计一个不能被继承的类
  6. 设计一个只能创建一个对象的类(单例模式)
  7. 饿汉模式
  8. 懒汉模式
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Stable Diffusion ControlNet 基础使用指南
  • AI 辅助 Windows EXE 文件反编译技术实践
  • Cobalt Strike 魔改二开:Checksum8 算法、Beacon 密钥与 Stager 流量生成机制
  • Python 异步编程与协程实战
  • Cloudflare AI Gateway 接入 Google Gemini 指南
  • GitHub Copilot Pro 学生认证全流程指南
  • OpenClaw 构建飞书 AI 办公机器人:本地 Ollama 接入与 Skills 自动化
  • Antigravity Tools 基于 Rust+Tauri 的 AI 工作流重构实践
  • 现阶段大模型的主要行业应用场景分析
  • Linux 基础操作与 Java 项目云端部署实战
  • OpenClaw 接入飞书机器人并集成 Ollama 本地大模型实战
  • WebRTC 一对一通话技术详解
  • 模拟算法:核心概念与经典例题实践
  • HQL 命名参数与 Query 接口的分页查询
  • AI 生成表格导出指南:三种技术路径与代码实现
  • IDEA 中可免费使用的 AI 代码提示插件推荐
  • 企业微信外部群机器人主动推送消息实现指南
  • Ubuntu 前端开发环境搭建与 Vue 实战
  • Apache Tomcat 高危路径遍历漏洞 CVE-2025-55752 修复指南
  • 向日葵连接 Ubuntu 22.04 无显示器黑屏解决方案

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online