2017-05-31 49 views
0

我想實現一個數據結構,這是一個結構數組。該結構具有指向unsigned intunsigned short int的指針。使用指向int或short int的成員創建struct數組?

我的第一次嘗試是將結構的數據成員指向基類。基類有兩個派生類。這兩個g ++以及鐺一聲錯誤(沒有成員在「基地」命名爲「myarray的」)

在我的第二次嘗試,我用空指針,但兩種編譯器再次給了一個錯誤(錯誤:指針的下標不完全類型 '無效')

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

我的問題是:

  1. 是否有可能實現我想象中的數據結構?

  2. 爲什麼我無法訪問派生類數據成員?

+1

如果你想訪問一個'void'指針後面的數據,你*有*來轉換該指針(這意味着你*有*知道它指向哪種類型的數據)。至於「基類」解決方案,你有同樣的問題:從基類訪問數組,它必須在其中聲明。而子類不能重新聲明一個屬性。 –

回答

1

事情是這樣的:

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

您還可以使用的unique_ptr爲載體,添加虛擬的方法來結構

+1

爲什麼我們需要重寫析構函數? – Zingo

+1

我的習慣,在這種情況下,你不需要它。 –

+0

我認爲你是對的,因爲通用規則的基礎析構函數「必須」是虛擬的。我在Professional C++第三版第9章中找到了以下注釋:第9章 – Zingo

2

「正確」 的解決辦法是使用模板。但要解決你的問題,void*可以指向任何東西和編譯器不知道它實際指向什麼。你必須將指針轉換爲正確的類型:

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

感謝您的更正,如果您解釋如何使用模板來解決此問題,我將非常感激。 – Zingo