2017-05-31 1 views
0

Ich versuche, eine Datenstruktur zu implementieren, die ein Array von Strukturen ist. Die Struktur hat einen Zeiger auf entweder unsigned int oder unsigned short int.Erstellen von struct-Arrays mit Elementen, die entweder auf int oder auf kurze int zeigen?

Mein erster Versuch ist der Datenelementpunkt der Struktur zu einer Basisklasse. Die Basisklasse hat zwei abgeleitete Klassen. Sowohl g ++ und Klirren gab einen Fehler (kein Mitglied namens ‚myArray‘ in ‚Basis‘)

In meinem zweiten Versuch habe ich void-Zeiger, aber beide Compiler gab wieder einen Fehler (Fehler: Index der Zeiger auf unvollständiger Typ 'VOID')

struct Base { uint32_t *x; }; 
struct Derived16 : public Base { uint16_t *myArray; }; 
struct Derived32 : public Base { uint32_t *myArray; }; 

struct SpecialStruct { 
    char *name; 
    uint32_t id; 
    Base *specialArray; 
}; 

struct SpecialStruct2 { 
    char *name; 
    uint32_t id; 
    void *specialArray; 
}; 

int main() { 
    // First Attempt 
    SpecialStruct myStructs[10]; 
    myStructs[0].specialArray = new Derived32; 
    myStructs[1].specialArray = new Derived16; 

    myStructs[0].specialArray->x = new uint32_t[10]; 
    myStructs[0].specialArray->myArray = new uint32_t[10]; 
    // ^-- error: no member named 'myArray' in 'Base' 

    // Second Attempt 
    SpecialStruct2 myStructs2[10]; 
    myStructs2[0].specialArray = new uint32_t[10]; 
    myStructs2[1].specialArray = new uint16_t[10]; 

    myStructs2[1].specialArray[0] = 1; 
    // ^-- error: subscript of pointer to incomplete type 'void' 

    return 0; 
} 

Meine Fragen sind:

  1. Ist es möglich, meine imaginäre Datenstruktur zu erreichen?

  2. Warum kann ich nicht auf abgeleitete Klassenmitglieder zugreifen?

+1

Struct Wenn Sie zugreifen möchten Die Daten hinter einem "void" -Zeiger haben Sie *, um diesen Zeiger zu erzeugen (was bedeutet, dass Sie * wissen müssen, um welche Art von Daten es verweist). Was die "Basisklassen" -Lösung betrifft, haben Sie das gleiche Problem: Um auf das Array von der Basisklasse aus zuzugreifen, muss es in ihm deklariert werden. Und untergeordnete Klassen können ein Attribut nicht erneut deklarieren. –

Antwort

1

Etwas wie folgt aus:

struct BaseStruct{ 
    virtual ~BaseStruct() {} 
}; 

template<class T> 
struct SpecialStruct: public BaseStruct{ 
    char *name; 
    uint32_t id; 
    T * spcialArray; 
    public: 
    virtual ~SpecialStruct(){} 
}; 


int main() { 

    // First Attempt 
    vector < BaseStruct*> myStructs; 

    SpecialStruct<uint32_t> * myStruct =new SpecialStruct<uint32_t>; 
    myStruct->spcialArray = new uint32_t[10]; 
    myStruct->spcialArray[0] = 1; 

    myStructs.push_back(myStruct); 
    SpecialStruct<uint32_t>* t = (SpecialStruct<uint32_t>*) myStructs[0]; 
    cout << t->spcialArray[0]; 
    return 0; 
} 

Sie können auch unique_ptr für Vektor verwenden und virtuelle Methoden hinzufügen

+1

Warum müssen wir den Destruktor überschreiben? – Zingo

+1

Meine Gewohnheit, in diesem Fall brauchen Sie es nicht. –

+0

Ich denke, du hast recht, als allgemeine Regel muss der Basisdestruktor "virtuell" sein. Ich fand den folgenden Kommentar in Professional C++, dritte Ausgabe, Kapitel 9 – Zingo

2

Die "richtige" Lösung Vorlagen zu verwenden wäre. Aber um Ihr Problem zu lösen, kann ein void* auf alles zeigen und der Compiler weiß nicht, worauf er eigentlich hinweist. Sie haben den Zeiger auf den richtigen Typ zu werfen:

static_cast<Derived32*>(myStructs[0].spcialArray)->x = ...; 
+0

danke für die Korrektur, und ich wäre sehr dankbar, wenn Sie erklären, wie Sie Vorlagen verwenden, um dieses Problem zu lösen. – Zingo

Verwandte Themen