2016-12-18 1 views
0

Ich versuche, die folgende C# Funktionalität in C++, aber es gibt jetzt viel mehr ich darüber nachdenken müssen neu zu schreiben:ein Objekt der abstrakten Basisklasse Art Vorlagen und/oder typeof() instanziiert mit

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; 
     } 
    } 
} 

Dies ist so weit, wie ich bekam:

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; 
} 

googeln und sich auf Vorlagen Lesung bis tat, aber an diesem Punkt, den ich glaube, ich brauche einen erfahrenen Programmierer auf diese anzuzeigen. Bin ich auf dem richtigen Weg? Ich erhalte "nicht aufgelöste externe Symbol" -Fehler und der C++ - Code validiert nicht, dass er eine Unterklasse des richtigen Typs erstellt. Ich weiß, dass dies ein paar Themen umfassen könnte, aber es wäre großartig, wenn mir jemand helfen könnte!

+2

"typeof" ist ein C# Hack -spezifische. Obwohl es in C++ einige ähnliche Konstrukte gibt, werden sie als schlechte Programmierpraktiken angesehen. Die richtige Lösung ist hier, virtuelle Methoden entsprechend zu verwenden. –

+0

@SamVarshavchik Danke für den Kommentar. Mir ist bewusst, dass "typeof" sowohl C# -spezifisch als auch unerwünscht zu verwenden ist. Ich hätte es wahrscheinlich nicht erwähnen sollen. Wenn Sie einen Moment Zeit haben, eine Antwort zu geben, wäre ich an Ihrem Vorschlag interessiert! –

Antwort

0

Ich denke, der richtige Weg ist, mit intelligenten Zeigern zu experimentieren. Hier einige sfinae basierten Ansatz etwas das gleiche tun, wie Sie in Ihrem C# Lösung tat

#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 
} 

[live demo]

+0

Vielen Dank für Ihre Antwort. Damit hast du mich dazu gebracht, über die Template-Metaprogrammierung zu lesen, die sich wie ein gutes Thema anfühlt, um auf dem Laufenden zu bleiben. Ich denke, dass ich auf die zusätzliche Methode für sfinae verzichten werde, ein Compiler-Fehler ist wahrscheinlich die richtige Sache in diesem Fall zu sehen. –

+0

Wenn Sie eine dedizierte Fehlermeldung beim Missbrauch Ihrer Addierfunktion anstelle von sfinae auslösen möchten, können Sie die Verwendung von static_assert in Betracht ziehen –

Verwandte Themen