我试图在C ++中重写以下C#功能,但现在我需要考虑的更多:
public abstract class Component
{
}
public class Entity
{
private List<Component> m_components = new List<Component>();
public T AddComponent<T>() where T : Component
{
if (typeof(T).IsSubclassOf(typeof(Component)))
{
T newComponent = Activator.CreateInstance<T>();
m_components.Add(newComponent);
return newComponent;
}
else
{
return null;
}
}
public Component AddComponent(Type t)
{
if (t.IsSubclassOf(typeof(Component)))
{
Component newComponent = (Component)Activator.CreateInstance(t);
m_components.Add(newComponent);
return newComponent;
}
else
{
return null;
}
}
}
据我所知:
class Component
{
Component() { }
~Component() { }
void OnCreate() = 0;
}
class Entity
{
public:
template<class N> void Entity::AddComponent()
{
N *newComponent = new N();
m_components->push_back(newComponent);
newComponent->OnCreate();
}
private:
std::vector<Component*> *m_components;
}
谷歌搜索和阅读模板确实有一些好处,但在这一点上,我认为我需要有经验的程序员对此进行观察。我在正确的轨道上吗?我得到了未解决的外部符号&#39;错误和C ++代码没有验证它是否正在创建正确类型的子类。我很欣赏这可能包含几个主题,但如果有人能帮我一把,那就太好了!
答案 0 :(得分:0)
我认为正确的道路是尝试智能指针。这里有一些基于sfinae的方法与你在C#解决方案中做的有点相同:
#include <memory>
#include <vector>
#include <type_traits>
class Component {
public:
Component() { }
~Component() { }
virtual void OnCreate() = 0;
};
class Entity {
public:
template<class T> std::enable_if_t<std::is_base_of<Component, T>::value> AddComponent() {
auto inserted = std::make_shared<T>();
inserted->OnCreate();
m_components.push_back(std::move(inserted));
}
template<class T> std::enable_if_t<!std::is_base_of<Component, T>::value> AddComponent() {
}
private:
std::vector<std::shared_ptr<Component>> m_components;
};
class Component1: public Component {
public:
void OnCreate() { }
};
class Component2: public Component {
public:
void OnCreate() { }
};
class Component3 {
public:
void OnCreate() { }
};
int main() {
Entity e;
e.AddComponent<Component1>();
e.AddComponent<Component2>();
e.AddComponent<Component3>(); // won't add anything to your entity
// as Component3 is not a subclass of
// Component
}