2011-11-14 138 views
1

我有這段代碼,但是我沒有看到我在這裏出錯的地方。它似乎編譯好,但我不能訪問ComputerAppliance函數。有人可以幫助我瞭解如何在這個代碼示例中創建一個擁有不同對象的數組?創建不同對象的數組

#include <iostream> 
using namespace std; 

class Technics 
{ 
private: 
    int price, warranty; 
    static int objCount; 
    double pvn; 
    char *name, *manufacturer; 
public: 
    Technics() 
    { 
     this->objCount++; 
    }; 

    Technics(int price) 
    { 
     this->objCount++; 
     this->price = price; 
    } 

    ~Technics(){ 
     this->objCount = this->objCount - 2; 
    }; 

    static int getObjCount() 
    { 
     return objCount; 
    } 

    void setPrice(int price) 
    { 
     this->price = price; 
    } 

    int getPrice() 
    { 
     return this->price; 
    } 

    void resetCount() 
    { 
     this->objCount = 0; 
    } 
}; 
int Technics::objCount = 0; 

class Computer : public Technics 
{ 
private: 
    int cpu, ram, psu, hdd; 
public: 
    Computer() {} 
    Computer(int price) 
    { 
     this->setPrice(price); 
    } 

    void setCpu(int cpu) 
    { 
     this->cpu = cpu; 
    } 

    int getCpu() 
    { 
     return this->cpu; 
    } 
}; 

class Appliance : public Technics 
{ 
private: 
    int height; 
    int width; 
    char* color; 
    char* type; 

public: 
    Appliance(){} 
    Appliance(int height, int width) 
    { 
     this->height = height; 
     this->width = width; 
    } 

    void setWidth(int width) 
    { 
     this->width = width; 
    } 

    int getWidth() 
    { 
     return this->width; 
    } 
}; 

void main() 
{ 
    //Creating array 
    Technics *_t[100]; 

    // Adding some objects 
    _t[0] = new Computer(); 
    _t[1] = new Computer(); 
    _t[2] = new Appliance(); 

    // I can access only properties of Technics, not Computer or Appliance 
    _t[0]-> 

    int x; 
    cin >> x; 
} 
+3

可能最好拿起一本關於C++的好書,並圍繞着繼承和多態的概念。順便說一下,不存在「一組不同的對象」:所有的數組元素都是相同的類型,即'Technics *'。 –

+0

好吧,有一個陣列boost :: variant <...>,boost :: any或void *當然......(在不斷上升的程度上) – sehe

+0

當然你只能訪問Technics的屬性,因爲它是一個指針到'技術'。另外'Technics * _t [100]'是一個指向'Technics'數組的指針。這不是你想要的。請使用'std :: vector' –

回答

0

線:

_t[0] = new Computer(); 

創建陣列中的計算機對象並將其存儲爲一個工藝基礎指針(即,對於所有意圖和目的,而陣列中,這是一個工藝對象) 。

您需要轉換回派生類訪問在工藝比那些更派生成員:

static_cast<Computer*>(_t[0])->Your_Member(); 

使用dyncamic投,如果你不知道哪個派生類型是 - 它會返回成功和NULL上失敗鑄造指針所以這是怎樣的一個類型檢查的 - 它有大的運行時開銷了,所以儘量避免吧:)

編輯響應您的收評:

//Calculate the length of your dynamic array. 

//Allocate the dynamic array as a pointer to a pointer to Technics - this is like 
//Making an array of pointers each holding some Technics heirarchy object. 
Technics** baselist = new Technics*[some_length]; 

//Populate them the same way as before: 
baselist[0] = new Computer(); 
baselist[1] = new Appliance(); 

PS:你也可以使用std :: vector,它可以動態改變,而不是隻在運行時創建 - 如果允許使用它,這是最好的選擇。它可以節省您製作自己的可調整大小的數組代碼。谷歌它;)

+0

如果你不確定'_t [0]'是否爲'Computer',你可以使用'dynamic_cast'來代替,但是如果轉換失敗,可以返回NULL。 –

+0

你讀過那個答案的結尾了嗎:) –

+0

好吧,這應該教會我不要在一個窗口中操作系統,並在另一個窗口中工作。 :) –

0

這是因爲_t是指向Technics而不是ComputerAppliance

給技術一個「對象類型」參數例如一個枚舉TechnicsType.ComputerComputerTechnicsType.ApplicanceAppliance,檢查並轉換爲適當的類型以獲取類方法。

0

是的,您只能訪問Technics的屬性,因爲您的變量的類型爲Technics。您必須將其轉換爲計算機或設備類才能執行其他方法。

你真的得在這裏考慮一下你的設計。它真的適合嗎?爲什麼你有同一個容器內的所有對象?特別是如果你有不同的方法調用..這是沒有道理的..

如果你真的想調用不同的方法,你可能必須使用switch聲明來決定你有什麼類型,然後調用appropiate方法(我想你想遍歷整個容器,否則沒有意義,有一個大的容器與不同的對象)。

0

的解決方案是非常非常簡單的:)

超類必須在類定義中聲明的子類的虛函數。

例如:如果超類計算機有一個亞類稱爲膝上型具有一個功能int getBatteryLife();,所以計算機類必須具有定義virtual int getBatteryLife()到的類型的指針的向量被稱爲電腦。

+0

這個解決方案的問題是,你必須在基類中聲明很多虛函數,每個子類屬性要使用一個。 –

0

因爲_tTechnics指針數組,所以不可能訪問派生類的屬性。使用這樣的訪問者模式或向下滾動指針:

// visitor pattern 
class Visitor 
{ 
    void accept(Appliance &ref) { // access Appliance attributes }; 
    void accept(Computer & ref) { // access Computer attributes }; 
}; 

class Technics 
{ 
    .... 
    virtual void visit(Visitor &) = 0; 
}; 

class Appliance 
{ 
    .... 
    virtual void visit(Visitor &v) { v.accept(*this); } 
}; 

class Computer 
{ 
    .... 
    virtual void visit(Visitor &v) { v.accept(*this); } 
};