一、设计一个类,不能被拷贝
cpp
class Copyban {
public:
Copyban() {};
Copyban(const Copyban& cp) = delete;
Copyban& operator=(const Copyban& cp) = delete;
};
如上设计的类通过delete禁止了拷贝构造和赋值,根据实际情景,还可以禁掉移动拷贝构造和移动赋值。
二、设计一个类,只能在堆上创建对象
cpp
class Heaponly {
public:
static Heaponly* CreateObj()
{
return new Heaponly;
}
private:
Heaponly() {};
Heaponly(const Heaponly& h) = delete;
};
将构造函数设为私有,这样在外部就不会在栈上创建对象,同时将拷贝构造屏禁掉,就不能通过拷贝构造在栈上创建对象了。
三、设计一个类,只能在栈上创建对象
cpp
class stackonly {
public:
stackonly CreateObj()
{
return stackonly();
}
void* operator new(size_t size) = delete;
void operator delete(void* ptr) = delete;
private:
stackonly():
_a(0)
{}
int _a;
};
将构造函数私有,这样在类外面就不能使用构造函数,同时为了避免new 的使用,重载new,将new禁掉。
四、创建一个类,只能创建一个对象
单例模式可以再细分为懒汉模式和饿汉模式,这两者的区别就在于在main函数之后才能生成对象,而饿汉模式在编译时就创建了对象。
| 特性 | 饿汉模式(类内 static 成员) | 懒汉模式(函数内 static 变量) |
|---|---|---|
| 是否需要类外定义 | ✅ 是 | ❌ 否 |
| 内存分配时机 | 程序启动时(main 前) | 第一次调用函数时 |
| 初始化顺序风险 | ⚠️ 有(Static Initialization Order Fiasco) | ✅ 无 |
| 代码复杂度 | 较高(需 .cpp 文件) | 极简(全在头文件) |
所以现代 C++ 更推荐懒汉模式(用局部 static),不仅线程安全,还避免了定义分离和初始化顺序问题。
你现在完全理解了 C++ 静态成员的声明与定义机制!这是写出正确、可链接代码的基础。继续加油!
cpp
class LazySingleton {
public:
static LazySingleton& getInstance()
{
static LazySingleton ls;
return ls;
}
LazySingleton(const LazySingleton& ls) = delete;
LazySingleton& operator=(const LazySingleton& ls) = delete;
private:
LazySingleton() = default;
};
class EagerSingleton {
public:
static EagerSingleton es;
static EagerSingleton& getInstance()
{
return es;
}
EagerSingleton(const EagerSingleton& e) = delete;
EagerSingleton& operator=(const EagerSingleton& e) = delete;
private:
EagerSingleton() = default;
};
EagerSingleton EagerSingleton::es;