如何在C++中不使用模板实现Actor创建函数?
替代模板实现CreateActor的正确方案
先明确你现有实现的核心问题:
- 用
memcpy_s复制非POD类型的C对象完全违背C对象模型,对于包含虚函数、动态内存成员(如std::string、容器)的类,会直接破坏对象内部状态,引发崩溃或未定义行为 - 强制要求调用者创建dummy实例,不仅增加调用成本,还存在内存所有权冲突(函数内
delete用户创建的对象,违背内存管理原则)
以下是两种可靠的非模板实现方案:
方案一:使用创建回调函数指针
通过让调用者提供一个创建对应Actor子类实例的函数,绕过模板实现类型创建,完全符合原模板函数的语义(创建全新实例)。
实现代码
首先定义回调函数类型:
// 定义创建Actor的函数指针类型,返回EngineActor指针 using ActorCreator = EngineActor* (*)();
修改后的CreateActor函数:
void* CreateActor(ActorCreator creator) { if (!creator) return nullptr; EngineActor* newActor = creator(); if (newActor) { newActor->SetParent(this); newActor->Start(); } return newActor; }
调用示例
假设你要创建PlayerActor(继承自EngineActor):
// 定义创建PlayerActor的回调函数 EngineActor* CreatePlayer() { return new PlayerActor(); } // 调用CreateActor,自行转换为目标类型 PlayerActor* player = static_cast<PlayerActor*>(CreateActor(CreatePlayer));
方案二:原型模式(基于虚函数克隆)
如果允许修改基类EngineActor,可以通过添加虚克隆方法,让子类实现自身的拷贝逻辑,避免手动创建dummy的麻烦,同时保证对象创建的正确性。
实现步骤
- 修改基类
EngineActor,添加纯虚克隆方法:
class EngineActor { public: // 纯虚克隆方法,子类需实现自身的拷贝逻辑 virtual EngineActor* Clone() const = 0; // 原有成员:SetParent、Start等 virtual void SetParent(void* parent) = 0; virtual void Start() = 0; };
- 子类实现Clone方法:
class PlayerActor : public EngineActor { public: EngineActor* Clone() const override { // 调用拷贝构造函数创建新实例 return new PlayerActor(*this); } // 实现基类的纯虚方法 void SetParent(void* parent) override { /* 具体实现 */ } void Start() override { /* 具体实现 */ } };
- 修改CreateActor函数:
EngineActor* CreateActor(const EngineActor* prototype) { if (!prototype) return nullptr; EngineActor* newActor = prototype->Clone(); newActor->SetParent(this); newActor->Start(); return newActor; }
调用示例
用栈上的原型实例即可,无需动态分配:
PlayerActor prototype; PlayerActor* player = static_cast<PlayerActor*>(CreateActor(&prototype));
这两种方案都遵循C++对象模型,避免了你的原方法带来的各种问题,且不需要使用模板。
内容的提问来源于stack exchange,提问作者nyori
相关产品推荐
相关产品推荐

