我有一个抽象类“Entity”。我想防止手动调用其派生类的构造函数和析构函数。
要创建和销毁此类的实例,我使用以下函数:
template <typename T, typename... Args, typename = std::enable_if_t< !std::is_same_v<Entity, T> && std::is_base_of_v<Entity, T> && std::is_constructible_v<T, Args...>>>
T* SpawnEntity(Args&&... args)
{
T* instance = new T(std::forward<Args>(args)...);
// ... perform other operations ...
return instance;
}
void Destroy(Entity* entity) { ... }
如果手动调用任何扩展 Entity 的类的构造函数/析构函数,是否可能引发异常或编译错误?
编辑:我无法控制Entity的所有派生类,因此我无法将构造函数定义为私有。
您几乎无法阻止其他程序员故意规避类型系统,但您肯定可以防止意外发生。
如果您有一个“关键”用户定义类型,它具有私有构造函数(但公共复制构造函数)和您的工厂函数(模板)的朋友,并向每个构造函数添加此类型的“锁定”参数,则派生类可以轻松地将“lock”参数添加到其构造函数中,并将其转发给基类。然后派生的构造函数也都被锁定到您的工厂函数。
可以规避吗?是的,“锁”将接受
std::declval()
的结果,绕过构造函数的访问检查。但这需要明确的意图。