只能在栈上创建对象
🧱 一、类整体设计目标
我们想要实现:
只能在栈上创建对象,禁止在堆上
new
出来。
例如:
StackOnly obj; // ✅ OK:在栈上创建
StackOnly* p = new StackOnly(); // ❌ 编译错误:禁止 new
🚦 二、类的结构拆解
🔹 构造函数与析构函数
StackOnly() {std::cout << "构造 StackOnly" << std::endl;
}~StackOnly() {std::cout << "析构 StackOnly" << std::endl;
}
- 正常的构造和析构,用来观察创建/销毁过程。
- 由于我们只允许栈上创建,析构函数可以是 public 的。
🔹 成员函数
void print() {std::cout << "我是只能在栈上创建的对象" << std::endl;
}
普通成员函数,没特别之处。
🔹 禁止复制操作(可选但推荐)
StackOnly(const StackOnly&) = delete;
StackOnly& operator=(const StackOnly&) = delete;
❓ 为什么推荐禁用?
因为即使你禁止了 new
,如果没禁用复制,有人可以写:
StackOnly obj1;
StackOnly* p = new StackOnly(obj1); // ❌ 还是绕过你了
所以把复制构造和赋值操作都 = delete
是安全做法,防止被“曲线救国”。
🔹 核心点:禁用堆分配
void* operator new(size_t) = delete;
void operator delete(void*) = delete;
✅ 这是关键操作!
operator new
是在使用new
时会被调用的函数;operator delete
是在使用delete
时调用的函数;
你把它们 = delete
,编译器在编译期就会报错,强制禁止堆上创建对象。
💡 你可以试着写一组测试代码:
int main() {StackOnly obj; // ✅ OKobj.print();StackOnly* p = new StackOnly(); // ❌ error: use of deleted functiondelete p; // ❌ error: use of deleted function
}
运行结果:
构造 StackOnly
我是只能在栈上创建的对象
析构 StackOnly
✅ 总结
目的 | 方法 |
---|---|
禁止堆上创建 | operator new/delete = delete; |
禁止对象复制 | 拷贝构造 / 赋值操作 = delete |
保留正常栈上使用能力 | 构造函数/析构函数保持 public |
📌 延伸:如果你想做“只能在堆上创建”的类呢?
那就相反处理:
- 构造函数设为
private
; - 提供
static create()
; - 析构函数私有 + friend(防止用户 delete);