2017-02-04 3 views
2

Statische Code-Analyse-Tools ist in der Regel viel über „einziehe eine Basisklasse auf eine abgeleitete Klasse“ schweifen und ich fand auch ein paar Standard-Führer der Codierung, die diese so nicht zu tun, erwähnt ich war frage mich, was ist der Best-Practice-Weg.einziehenden Best-Practice (C++)

Hier ist meine Anwendungsfall:

ich eine Base (Schnittstelle) haben, DerivedA, DerivedB Klassen und dann ein Array Basiszeiger enthält.

Dann Iterate durch das Array und basierend auf einem Flag, ich feststellen, ob das Objekt DerivedA oder DerivedB ist, werfen Sie es nieder und einige zufällige Sachen zu dem Objekt von außen.

Im Grunde so etwas wie diese:

// arr is of type Base** 
for (int i = 0; i < size; ++i) 
{ 
    // doMagic has an overload for both types 
    if (arr[i]->isDerivedA()) 
    { 
     doMagic(reinterpret_cast<DerivedA*>(arr[i])); 
    }  
    else if (arr[i]->isDerivedB()) 
    { 
     doMagic(reinterpret_cast<DerivedB*>(arr[i])); 
    } 
} 

Bout die reinterpret, kann ich nicht wegen Embedded-Plattform Einschränkungen verwenden dynamic_cast (das gleiche gilt für 11 C++), aber die Basisklasse, dass das Objekt eine Schnittstelle garantiert sein ist entweder DerivedA oder DerivedB.

Ich könnte DerivedA und DerivedB nur reine virtuelle Aufrufe implementieren, so würde ich keine Angst vor dem Downcasting etwas haben müssen, aber die DerivedA und DerivedB Klassen sind sehr spezialisiert und DoMagic macht völlig andere Dinge mit den Instanzen ...

Also habe ich mich gefragt, wie ihr euch nähert - mit einem einzigen Array von sehr unterschiedlichen Objekten, aber geerbt von einer einzigen Basis, durch sie hindurch und einige spezialisierte Sachen von außen.

+0

Man muss sich fragen, warum 'DerivedA' und' DerivedB' von 'Base' alle auf abgeleitet sind. Was ist der Zweck von "Base"? –

+0

Sie haben einige gemeinsame Methoden enthalten, damit ich nicht mit denen und auch einige gemeinsame Datenelemente neu implementieren wollen. Sagen wir es ist 50/50 :). Beispiel hätte Klassen wie: Nachricht, JsonMessage, XmlMessage - und Methoden parseMessage (JsonMessage *), parseMessage (XmlMessage *) – Maci

+0

Vielleicht wäre eine sauberere Architektur die allgemeinen Methoden und Daten in eine dritte Klasse zu wickeln und eine HAS zu verwenden -Eine Beziehung zu dieser dritten Klasse statt. Vererbung für Implementierungen ist normalerweise kein gutes OOP-Design. –

Antwort

2

Sie sollten wahrscheinlich versuchen Besuchermuster zu verwenden. Hier ist ein einfaches Beispiel:

#include <cstdio> 

class A; 
class B; 
class Visitor { 
public: 
    void visit(A &a) { 
     printf("Visited A\n"); 
    } 

    void visit(B &) { 
     printf("Visited B\n"); 
    } 
}; 


class A { 
public: 
    virtual ~A() { } 

    virtual void applyVisitor(Visitor &v) { 
     v.visit(*this); 
    } 
}; 

class B : public A { 
public: 
    ~B() override { } 

    void applyVisitor(Visitor &v) override { 
     v.visit(*this); 
    } 
}; 


int main() { 
    A a; 
    B b; 

    Visitor v; 

    a.applyVisitor(v); 
    b.applyVisitor(v); 


    return 0; 
} 
+0

Danke, das so ziemlich entfernt die niedergeschlagenen und scheint cleaner - nur ein bisschen mehr Code erforderlich ist. – Maci

1

Wenn Sie wissen, dass ein Zeiger einer Basisklasse auf ein Objekt einer abgeleiteten Klasse, können Sie static_cast verwenden. Der Compiler entsprechenden Code einfügen Offsets einzustellen, im Gegensatz zu reinterpret_cast oder einem C-Cast.