C++ 特殊类设计

一、设计一个不能拷贝的类

核心思想

禁止调用拷贝构造 + 赋值运算符重载

1. C++98 方式(私有化+只声明不定义)

cpp 复制代码
class CopyBan
{
private:
    // 只声明,不实现 + 设为私有
    CopyBan(const CopyBan&);
    CopyBan& operator=(const CopyBan&);
};

2. C++11 方式(=delete)

cpp 复制代码
class CopyBan
{
public:
    // 删除默认拷贝函数
    CopyBan(const CopyBan&) = delete;
    CopyBan& operator=(const CopyBan&) = delete;
};

二、设计一个只能在堆上创建的类

核心思想

  • 构造函数私有
  • 禁用拷贝(防止在栈上拷贝出对象)
  • 提供静态工厂方法在堆上创建对象
cpp 复制代码
class HeapOnly
{
public:
    static HeapOnly* CreateObject()
    {
        return new HeapOnly;
    }

private:
    // 1. 构造函数私有
    HeapOnly() {}

    // 2. 防拷贝
    HeapOnly(const HeapOnly&) = delete;
};

使用方式

cpp 复制代码
HeapOnly* obj = HeapOnly::CreateObject();

三、设计一个只能在栈上创建的类

核心思想

  • 构造函数私有
  • 禁用 operator new(禁止在堆上创建)
  • 静态方法返回栈上临时对象
cpp 复制代码
class StackOnly
{
public:
    static StackOnly CreateObj()
    {
        return StackOnly();
    }

    // 禁掉 new / delete
    void* operator new(size_t size) = delete;
    void operator delete(void* p) = delete;

private:
    // 构造私有
    StackOnly() : _a(0) {}
    int _a;
};

使用方式

cpp 复制代码
StackOnly obj = StackOnly::CreateObj();

四、设计一个无法被继承的类

1. C++98 方式(构造私有)

cpp 复制代码
class NonInherit
{
public:
    static NonInherit GetInstance()
    {
        return NonInherit();
    }
private:
    NonInherit() {} // 派生类无法调用构造
};

2. C++11 方式(final 关键字)

cpp 复制代码
class A final
{
    // 该类不能被继承
};

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

概念

一个类永远只能创建一个实例,全局唯一。


1. 饿汉模式(Eager)

特点

  • 程序启动时就创建对象
  • 绝对线程安全
  • 简单粗暴
cpp 复制代码
class Singleton
{
public:
    static Singleton& GetInstance()
    {
        return m_instance;
    }

private:
    // 构造私有
    Singleton() {}

    // 防拷贝
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    // 静态对象,程序启动即初始化
    static Singleton m_instance;
};

// 初始化
Singleton Singleton::m_instance;

优点

  • 线程安全
  • 简单
  • 无锁

缺点

  • 进程启动慢
  • 多个单例初始化顺序不可控

2. 懒汉模式(Lazy)

特点

  • 第一次使用时才创建
  • 延迟加载
  • 必须保证线程安全(双检查锁)
cpp 复制代码
class Singleton2
{
public:
    static Singleton2* GetInstance()
    {
        // 双检查锁 DCL
        if (m_pInstance == nullptr)
        {
            m_mtx.lock();
            if (m_pInstance == nullptr)
            {
                m_pInstance = new Singleton2();
            }
            m_mtx.unlock();
        }
        return m_pInstance;
    }

    // 垃圾回收(自动释放)
    class CGarbo
    {
    public:
        ~CGarbo()
        {
            if (m_pInstance)
                delete m_pInstance;
        }
    };

    static CGarbo Garbo;

private:
    Singleton2() {}
    Singleton2(const Singleton2&) = delete;
    Singleton2& operator=(const Singleton2&) = delete;

    static Singleton2* m_pInstance;
    static mutex m_mtx;
};

// 静态变量初始化
Singleton2* Singleton2::m_pInstance = nullptr;
mutex Singleton2::m_mtx;
Singleton2::CGarbo Singleton2::Garbo;

优点

  • 进程启动快
  • 延迟初始化
  • 多单例可控制顺序

缺点

  • 复杂
  • 需考虑线程安全

六、总结

需求 核心方法
不能拷贝 禁拷贝构造 + 赋值重载
只能在堆上 构造私有 + 静态工厂返回 new
只能在栈上 禁 new + 静态工厂返回栈对象
不能被继承 final / 构造私有
单例模式 饿汉(启动创建)/ 懒汉(首次创建)

七、完整代码(笔记版可直接运行)

cpp 复制代码
#include<iostream>
#include <mutex>
#include <thread>
using namespace std;

// 1. 不能拷贝
class CopyBan
{
    CopyBan(const CopyBan&) = delete;
    CopyBan& operator=(const CopyBan&) = delete;
};

// 2. 只能在堆上
class HeapOnly
{
public:
    static HeapOnly* CreateObject()
    {
        return new HeapOnly;
    }
private:
    HeapOnly() {}
    HeapOnly(const HeapOnly&) = delete;
};

// 3. 只能在栈上
class StackOnly
{
public:
    static StackOnly CreateObj()
    {
        return StackOnly();
    }
    void* operator new(size_t size) = delete;
    void operator delete(void* p) = delete;
private:
    StackOnly() :_a(0) {}
    int _a;
};

// 4. 不能被继承
class A final
{};

// 5. 单例模式

// 饿汉
class Singleton
{
public:
    static Singleton& GetInstance()
    {
        return m_instance;
    }
private:
    Singleton() {}
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    static Singleton m_instance;
};
Singleton Singleton::m_instance;

// 懒汉
class Singleton2
{
public:
    static Singleton2* GetInstance()
    {
        if (nullptr == m_pInstance)
        {
            m_mtx.lock();
            if (nullptr == m_pInstance)
            {
                m_pInstance = new Singleton2();
            }
            m_mtx.unlock();
        }
        return m_pInstance;
    }

    class CGarbo
    {
    public:
        ~CGarbo()
        {
            if (Singleton2::m_pInstance)
                delete Singleton2::m_pInstance;
        }
    };
    static CGarbo Garbo;

private:
    Singleton2() {}
    Singleton2(const Singleton2&) = delete;
    Singleton2& operator=(const Singleton2&) = delete;
    static Singleton2* m_pInstance;
    static mutex m_mtx;
};

Singleton2* Singleton2::m_pInstance = nullptr;
mutex Singleton2::m_mtx;
Singleton2::CGarbo Singleton2::Garbo;
相关推荐
吃好睡好便好1 小时前
在Matlab中绘制圆锥三维曲面图
开发语言·人工智能·学习·算法·matlab·信息可视化
摇滚侠1 小时前
并发编程 Java 面试题 真正的 offer 偏方 Java 基础 Java 高级
java·开发语言
JAVA学习通3 小时前
北京明光云振铎数据科技Java面经
java·开发语言·科技
jerryinwuhan9 小时前
基于各城市站点流量的复合功能比较
开发语言·php
迈巴赫车主10 小时前
Java基础:list、set、map一遍过
java·开发语言
智者知已应修善业10 小时前
【51单片机89C51及74LS273、74LS244组成】2022-5-28
c++·经验分享·笔记·算法·51单片机
南 阳11 小时前
Python从入门到精通day66
开发语言·python
十八旬12 小时前
快速安装ClaudeCode完整指南
开发语言·windows·python·claude
前进的李工12 小时前
EXPLAIN输出格式全解析:JSON、TREE与可视化
开发语言·数据库·mysql·性能优化·explain