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>> 管理游戏对象,这是游戏场景的最佳实践——独占所有权、自动清理、支持多态扩展。后续添加 PlayerEnemy 等子类时,建议引入工厂函数来封装创建逻辑。

posted @ 2026-05-21 16:20  菜鸟老李  阅读(14)  评论(0)    收藏  举报