c++23创建类的实例方法
C++ 创建类型实例的方法
C++ 提供了多种对象构造方式,按存储位置分为 栈分配、堆分配 和 自定义内存 三类。
1. 栈分配(自动存储期)
Object obj(100, 200, 50, 50, red);
GameApp app;
| 维度 | 评价 |
|---|---|
| 性能 | 最快,仅移动栈指针 |
| 生命周期 | 离开作用域自动析构 |
| 多态 | 不支持(对象切片风险) |
| 内存 | 受栈空间限制(通常 1~8 MB) |
适用:局部变量、作用域明确的小对象。
2. 原始指针 + new/delete
Object* obj = new Object(100, 200, 50, 50, red);
delete obj;
| 维度 | 评价 |
|---|---|
| 性能 | 堆分配较慢 |
| 生命周期 | 灵活,但需手动 delete |
| 多态 | 支持 |
| 安全性 | 易泄漏、双重释放、悬垂指针 |
结论:现代 C++ 应避免。用方案 3 替代。
3. std::unique_ptr(独占所有权)
auto obj = std::make_unique<Object>(100, 200, 50, 50, red);
objects.push_back(std::move(obj)); // 所有权转移
| 维度 | 评价 |
|---|---|
| 性能 | 零额外开销(与原始指针对齐) |
| 生命周期 | 自动析构,RAII 保证异常安全 |
| 多态 | 支持,unique_ptr<Base> = make_unique<Derived>() |
| 拷贝 | 禁止,仅可移动 |
适用:容器管理、所有权传递。项目当前即用此方案。
4. std::shared_ptr(共享所有权)
auto obj = std::make_shared<Object>(100, 200, 50, 50, red);
auto obj2 = obj; // 引用计数 → 2
| 维度 | 评价 |
|---|---|
| 性能 | 引用计数有开销(原子操作 + 16 字节控制块) |
| 生命周期 | 最后一个 shared_ptr 销毁时析构 |
| 多态 | 支持 |
| 缺陷 | 循环引用导致内存泄漏(需 weak_ptr 打破) |
适用:多个所有者需要共享同一对象的场景。
5. std::optional(延迟初始化)
std::optional<Object> obj; // 未构造
obj.emplace(100, 200, 50, 50, red); // 需要时构造
| 维度 | 评价 |
|---|---|
| 性能 | 无堆分配,额外 bool 存储 |
| 多态 | 不支持 |
| 语义 | 明确表达"可能不存在" |
适用:初始化参数稍后才能确定的场景。
6. Placement new(原地构造)
alignas(Object) std::byte buffer[sizeof(Object) * N];
auto* obj = new (&buffer[0]) Object(100, 200, 50, 50, red);
obj->~Object(); // 必须手动析构
| 维度 | 评价 |
|---|---|
| 性能 | 零堆分配,自定义内存布局 |
| 生命周期 | 完全手动管理 |
| 安全性 | 极易出错,构造/析构必须配对 |
适用:对象池、std::vector 等容器的底层实现。应用层几乎不需要。
7. 工厂函数
// 简单工厂
std::unique_ptr<Object> CreateObject(ObjectType type) {
switch (type) {
case ObjectType::Player: return std::make_unique<Player>();
case ObjectType::Enemy: return std::make_unique<Enemy>();
}
}
| 维度 | 评价 |
|---|---|
| 灵活性 | 封装创建逻辑,便于集中管理 |
| 多态 | 返回基类指针,调用方与具体类型解耦 |
| 扩展性 | 新增子类只需改工厂内部 |
适用:存在多个子类、需要按配置/参数动态创建时。对当前项目扩展很有用。
决策指南
需要多态?
├─ 否 → 栈分配(局部变量)/ optional(延迟初始化)
└─ 是 → 谁拥有该对象?
├─ 唯一所有者 → unique_ptr + make_unique
├─ 多个所有者 → shared_ptr(注意循环引用)
└─ 不拥有(只观察)→ 原始指针 T*(仅作引用,不管理生命周期)
项目现状
当前项目 GameApp 使用 std::vector<std::unique_ptr<Object>> 管理游戏对象,这是游戏场景的最佳实践——独占所有权、自动清理、支持多态扩展。后续添加 Player、Enemy 等子类时,建议引入工厂函数来封装创建逻辑。

浙公网安备 33010602011771号