2016-05-11 5 views
1

Ich habe Hierarchie der Klassen:Was ist der beste Weg, um den Typ des Absenderobjekts zu kennen?

class A 
{ 
}; 

class B : public A 
{ 
}; 

class C : public B 
{ 
}; 

class D : public A 
{ 
}; 

und ich habe eine Funktion, die Benachrichtigung ausführt:

void notify(A* sender, const NotificationType notification) 
{ 
} 

Mein Problem ist, wie genaue Art des Senderobjekts zu erfahren. Ich möchte einen eleganten Weg finden, dieses Problem zu lösen. Ich mag es nicht, Dynamic Cast für diese Zwecke zu verwenden. Art und Weise ist, wie Enum innerhalb der Klasse A zu definieren:

enum ClassType 
{ 
    CLASS_A, 
    CLASS_B, 
    CLASS_C, 
    CLASS_D 
}; 

und definieren virtuelle Methode:

virtual ClassType get_type(void) const; 

Aber dieser Ansatz hat schlechte Skalierbarkeit. Eine weitere Möglichkeit, diese Informationen in NotificationType beizubehalten, weist jedoch auch eine schlechte Skalierbarkeit auf.

P.S. Ich möchte nur einen ähnlichen Code verwenden:

ich ähnlichen Code verwenden möchten:

void notify(A* sender, const NotificationType notification) 
{ 
    if (sender is object of A) 
     new GuiA(); 
    else if (sender is object of B) 
     new GuiB(); 
    else if (sender is object of C) 
     new GuiC(); 
    else 
     new GuiD(); 
} 
+9

"Wie finde ich den genauen Typ des Absenderobjekts?" Wenn Sie es wissen müssen, machen Sie es falsch. –

+2

Können Sie erklären, warum Sie den konkreten Typ des Absenders kennen müssen? – hansmaad

+4

Es scheint eigenartig, dass Sie die Anwendung so gestalten, dass sie polymorph wirkt und Sie dann den konkreten Typ kennen müssen. –

Antwort

2

Wenn Sie Typ wollen wissen, Ihre Hierarchie bestehen bleiben, conside Boost verwenden :: TypeIndex (http://www.boost.org/doc/libs/develop/doc/html/boost_typeindex.html).

Wenn Sie wissen möchten, dass Typ verschiedene Typen auf verschiedene Arten verarbeitet, berücksichtigen Sie Besucher Typ Typ oder verwenden abstrakte Schnittstelle mit virtuellen Funktionen deckt Ihre Bedürfnisse.

EDITED

Ihr Ziel ist es verschiedene UI-Objekt für verschiedene Typen zu erstellen. Sie können das folgende Modell verwenden, Ihr Ziel zu erreichen:

class UIObject {...}; 
class UIObjectFactory {...}; 
class A { 
public: 
    virtual std::unique_ptr<UIObject> Create(UIObjectFactory& factory) = 0; 
}; 

void OnNotify(A* sender) { 
    auto ptr = sender->Create(GetUIFactory()); 
    ... 
} 
2

Um ein passenden GUI-Objekt zu erstellen auf der Grundlage der konkreten Art der sender, könnten Sie eine Fabrik zu einer Art Factory-Methode in A passieren.

class A 
{ 
public: 
    virtual Agui* createGui(GuiFactory& fac) = 0; 
}; 

class GuiFactory 
{ 
public: 
    virtual Agui* forB(B&) = 0; 
    virtual Agui* forC(B&) = 0; 
    virtual Agui* forD(D&) = 0; 
}; 

class B : public A 
{ 
public: 
    Agui* createGui(GuiFactory& fac) 
    { 
     return fac.forB(*this); 
    } 
}; 

void notify(A* sender, const NotificationType notification) 
{ 
    // Use A interface... 
    // Get the concrete GuiFactory from somewhere, and use it 
    auto gui = sender->createGui(win32GuiFactory); 
} 
0

und definieren virtuelle Methode:

virtual ClassType get_type(void) const; 

Der einfachste Weg, dies zu erreichen und Skalierbarkeit Problem loszuwerden, ist Ihre get_type() Member-Funktion in jeder Klasse A, B, C zu implementieren , ... so:

typedef uintptr_t ClassType; 
virtual ClassType get_type() const 
{ 
    static int dummy; 
    return reinterpret_cast<ClassType>(&dummy); 
} 

Für jede Klasse, der Sie diese Memberfunktion hinzufügen, wird eine statische Variable dummy erstellt, sodass der Rückgabewert die Klasse eindeutig identifiziert.

Verwandte Themen