特殊类的设计

设计一个类,不能被拷贝

bash 复制代码
#include <iostream>
using namespace std;

// 禁止拷贝的类(标准写法)
class NonCopyable
{
public:
    // 1. 构造函数(正常写)
    NonCopyable() = default;

    // 2. 析构函数(正常写)
    ~NonCopyable() = default;

    // ========== 核心:禁用拷贝 ==========
    // 禁用拷贝构造函数
    NonCopyable(const NonCopyable&) = delete;

    // 禁用赋值运算符重载
    NonCopyable& operator=(const NonCopyable&) = delete;
};

继承自他的所有类都不能被拷贝

bash 复制代码
// 你的业务类,继承 NonCopyable → 自动禁止拷贝
class MyClass : public NonCopyable
{
    // 你的代码...
};
  • 子类要拷贝 → 必须先拷贝父类
  • 父类拷贝构造被 =delete 了
  • 子类自动无法生成拷贝函数

设计一个类,只能在堆上创建

bash 复制代码
#include <iostream>
using namespace std;

class HeapOnly
{
public:
    // 提供一个静态接口,专门用来在堆上创建对象
    static HeapOnly* createInstance()
    {
        return new HeapOnly(); // 在堆上创建
    }
    
		HeapOnly(const HeapONly& ) = delete;
		HeapOnly& operator=(const HeapONly& ) = delete;
		
    // 提供销毁接口(必须手动delete)
    void release()
    {
        delete this;
    }

private:
    // 🔴 核心:构造函数私有化!
    // 外部无法直接调用 → 不能在栈上创建对象
    HeapOnly()
    {
        cout << "对象在堆上创建啦!" << endl;
    }

    // 析构函数可以私有化
    ~HeapOnly()
    {
        cout << "对象在堆上销毁啦!" << endl;
    }
};

设计一个类,只能在栈上创建

bash 复制代码
#include <iostream>
using namespace std;

class StackOnly
{
public:
    StackOnly() {
        cout << "在栈上创建对象" << endl;
    }

    // 核心:禁用 堆上创建(new)
    void* operator new(size_t) = delete;
    void* operator new[](size_t) = delete; // 禁用数组new
};

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

让一个类,这个类的对象,在当前进程中,有且只有一个.

饿汉模式:一开始(main之前)就创建对象

问题:

  1. 如果单例对象数据过多,构造初始化成本较高,会影响程序的启动速度.
  2. 多个单例类有初始化启动依赖关系,饿汉无法控制
    例如:A和B两个单例,要求A先初始化,B后初始化,饿汉无法控制
bash 复制代码
#include <iostream>
#include <vector>
#include <string>
using namespace std;

//饿汉:一开始就创建出对象

class Singleton
{
public:
    static Singleton* GetInstance()
    {
        return &_sint;
    }
    void Print()
    {
        cout << _x << " " << _y << endl;
        for (const auto& str : _vstr)
        {
            cout << str << " ";
        }
        cout << endl;
    }
    void Addstr(const string& str)
    {
        _vstr.push_back(str);
    }
private:
    Singleton(int x = 0, int y = 0, const vector<string> &vstr = {"xxxx", "yyyy"})
        : _x(x), _y(y), _vstr(vstr) 
    {}
    int _x;
    int _y;
    vector<string> _vstr;

    //静态成员对象,不存在对象中,存在静态区,相当于全局的,定义在类中,受类域限制.
    static Singleton _sint; 
};

Singleton Singleton::_sint(1,1,{"aaa", "bbb", "ccc"}); //类外初始化

int main()
{
    Singleton *s1 = Singleton::GetInstance();
    s1->Print();
    s1->Addstr("ddd");
    Singleton *s2 = Singleton::GetInstance();
    s2->Print();
    return 0;
}

懒汉模式:调用时再初始化.

对比饿汉模式:程序一启动就直接把对象创建出来

懒汉模式:一开始只创建一个指针,等到使用的时候再把对象new出来

如下把GC回收机制也加入

bash 复制代码
#include <iostream>
#include <vector>
#include <string>
using namespace std;

// 饿汉:一开始就创建出对象
namespace hunger
{
    class Singleton
    {
    public:
        static Singleton *GetInstance()
        {
            return &_sint;
        }
        void Print()
        {
            cout << _x << " " << _y << endl;
            for (const auto &str : _vstr)
            {
                cout << str << " ";
            }
            cout << endl;
        }
        void Addstr(const string &str)
        {
            _vstr.push_back(str);
        }

    private:
        Singleton(int x = 0, int y = 0, const vector<string> &vstr = {"xxxx", "yyyy"})
            : _x(x), _y(y), _vstr(vstr)
        {
        }
        int _x;
        int _y;
        vector<string> _vstr;

        // 静态成员对象,不存在对象中,存在静态区,相当于全局的,定义在类中,受类域限制.
        static Singleton _sint;
    };
    Singleton Singleton::_sint(1, 1, {"aaa", "bbb", "ccc"}); // 类外初始化
}
namespace lazy
{
    class Singleton
    {
    public:
        static Singleton *GetInstance()
        {
            // 第一次调用时,创建单例对象
            // 线程安全问题,需要加锁
            // lock_guard<mutex> lock(mtx);
            // if (_psint == nullptr)
            // {
            //     _psint = new Singleton(1, 1, {"aaa", "bbb", "ccc"});
            // }
            // return _psint;

            static Singleton sint; // 局部静态变量,第一次调用时创建对象,线程安全
            //局部的静态生命周期时全局的
            return &sint;
        }
        static void DeInstance()
        {
            if (_psint)
            {
                delete _psint;
                _psint = nullptr;
            }
        }
        void Print()
        {
            cout << _x << " " << _y << endl;
            for (const auto &str : _vstr)
            {
                cout << str << " ";
            }
            cout << endl;
        }
        void Addstr(const string &str)
        {
            _vstr.push_back(str);
        }

    private:
        Singleton(int x = 0, int y = 0, const vector<string> &vstr = {"xxxx", "yyyy"})
            : _x(x), _y(y), _vstr(vstr)
        {
        }
        int _x;
        int _y;
        vector<string> _vstr;

        // 静态成员对象,不存在对象中,存在静态区,相当于全局的,定义在类中,受类域限制.
        static Singleton *_psint;

        //内部类
        class GC
        {
        public:
            ~GC()
            {
                Singleton::DeInstance();
            }
        };
        static GC gc; // 全局对象,在main函数结束后,析构函数会被调用,释放单例对象
    };
    Singleton *Singleton::_psint = nullptr; // 类外初始化
    static mutex mtx; // 锁
    Singleton::GC Singleton::gc;             // 类外初始化
}

int main()
{
    // Singleton *s1 = Singleton::GetInstance();
    // s1->Print();
    // s1->Addstr("ddd");
    // Singleton *s2 = Singleton::GetInstance();
    // s2->Print();
    lazy::Singleton *s3 = lazy::Singleton::GetInstance();
    s3->Print();
    s3->Addstr("ddd");
    lazy::Singleton *s4 = lazy::Singleton::GetInstance();
    s4->Print();
    return 0;
}
相关推荐
寰宇的行者1 天前
设计模式:单例模式
单例模式·设计模式
wangchunting2 天前
Java设计模式
java·单例模式·设计模式
不秃不少年3 天前
单例模式 (Singleton)
单例模式
程序员小寒6 天前
JavaScript设计模式(一):单例模式实现与应用
javascript·单例模式·设计模式
.select.6 天前
C++ 单例模式
java·c++·单例模式
bbq粉刷匠7 天前
Java--多线程--单例模式
java·开发语言·单例模式
砍光二叉树7 天前
【设计模式】创建型-单例模式
单例模式·设计模式
魑魅魍魉都是鬼7 天前
Android:java kotlin 单例模式
android·java·单例模式
biter down8 天前
C++ 单例模式:饿汉与懒汉模式
开发语言·c++·单例模式