2009-11-19 20 views
2

我需要指針和內存管理幫助。C++,不能使用數組或向量,我怎麼使用指針,通過這個爛攤子獲得?

我需要存儲不同的對象,從相同的基類的所有派生,並且已經使用陣列來做到這一點已但它是造成分割故障當陣列被填充有不同的對象。當數組已滿相同的派生類型的對象

我的程序工作正常。當陣列被填充有不同的物體它的工作原理,因爲它被認爲通過存儲在第一位置的對象,但然後當它切換到輸出的第二對象時,它給我的段錯誤。我知道這是一個內存訪問問題,但我不清楚如何根據用戶輸入來管理可變數量的對象。

THX, NMR

+4

請添加一些代碼片段,以便更好地理解您的問題。 – 2009-11-19 05:21:59

+1

您可以請發一小部分代碼,即基類A,派生類B,派生類C,以及您想要對它們做什麼? – mmr 2009-11-19 05:22:53

+1

std :: list objects; – 2009-11-19 05:48:39

回答

1

,因爲你已經確定了一個問題,家庭作業我不會發佈一個完整的解決方案,但我希望我可以幫你這個問題有點:

陣列旨在容納多個對象的相同的尺寸。將不同的對象存儲在數組中的問題(即使它們是從相同的基類派生的)是對象可能具有不同的大小。

您可以通過思考指針肯定是在正確的軌道上。

編輯(響應評論):

你會在看這樣的事:

BaseClass * array[size]; 
array[0] = new DerivedClass(...); 
array[1] = new OtherDerivedClass(...); 
... 

這種方法的缺陷是,沒有內置的缺失數組中的對象。您將通過有環和手動調用delete

for (int index = 0; index < size; index++) { delete array[index]; } 
+0

如果我使用基類指針的數組,每個指向不同的派生對象將工作?我想我已經嘗試過這種迭代,但無濟於事。或者我是否必須將每個指針的地址存儲到所述基指針數組中的派生對象?這是一個繞口令。 – ihtkwot 2009-11-19 05:34:24

+0

基類指針的數組絕對可以工作。 – 2009-11-19 05:40:35

+0

那個樣子的語法會是什麼樣子?我相當有信心,我的大腦現在正在被炸,我無法弄清楚語法。它會是: 類* Cptr; Class * cptr [size]; Cptr = new Derived(something,something); std :: cout << cptr [0] - > DerivedFunc(); 類似的東西? – ihtkwot 2009-11-19 05:59:14

5

確保你在堆棧上推指針動態分配。下面將失敗:

std::vector<Base*> objects; 

void make_one(void) 
{ 
    Derived d; 

    objects.push_back(&d); 
} 

因爲當函數結束時,類指向&d將被釋放。

std::vector<Base*> objects; 

void make_one(void) 
{ 
    Derived *d = new Derived; 

    objects.push_back(d); // a-ok 
} 

只記得要經過大功告成當載體,並呼籲他們delete:這是通過動態分配的對象緩解

struct deleter 
{ 
    template <typename T>  
    void operator()(T* pObject) const 
    { 
     delete pObject; 
    } 

} 

std::for_each(objects.begin(), objects.end(), deleter()); 

如果你可以使用升壓,有一個pointer container library這將爲你做這個。請注意,您不能使用auto_ptr並嘗試讓它爲您做; auto_ptr的容器打不好。

此外,請確保您的基類有虛析構函數:

struct base 
{ 
    virtual ~base(void) {} // important! 
} 

如果不是,在基類調用delete將只運行基本構造,泄漏的派生類中可能有任何資源。通過使其成爲虛擬的,編譯器可以跳轉到正確的析構函數。

+0

「只會運行基礎構造函數」......產生未定義的行爲,IIRC。 – 2009-11-19 09:23:12

+0

更好的是:直接使用正確的容器,如果你可以在http://www.boost.org/doc/libs/1_41_0/libs/ptr_container/doc/ptr_vector.html – 2009-11-19 14:48:23

+0

>> boost :: ptr_vector'爲了澄清,我們必須動態分配,因爲我們正在存儲指針,對吧?我們可以將常量對象存儲在一個向量中,而不必擔心函數結束時的釋放。 – Dave 2009-11-19 19:47:01

0

它看起來非常相似,這裏提到的問題:Is array of derived same as array of base?。你是否創建了一個派生對象的數組,並試圖訪問它,就好像它是一個基數組?

您可以使用基地指針這樣的陣列,但要注意,最好是使用std::vector<Base*>,而不是原始數組:

class Base 
{ 
public: 
    virtual ~Base(){} 
    virtual void f() {std::cout<<"Base::f()\n";} 
}; 


class Derived1: public Base 
{ 
public: 
    ~Derived1(){} 
    void f(){std::cout<<"Derived1::f()\n";} 
}; 

class Derived2: public Base 
{ 
public: 
    ~Derived2(){} 
    void f(){std::cout<<"Derived2::f()\n";} 
}; 


void print(Base** p, int count) 
{ 
    for(int i = 0; i < count; ++i) 
    { 
     (*p)->f(); 
     ++p; 
    } 
} 

int main() 
{ 
    Base b; 
    Derived1 d1; 
    Derived2 d2; 

    Base* arr[3]; 
    arr[0] = &b; 
    arr[1] = &d1; 
    arr[2] = &d2; 

    print(arr, 3); 


    return 0; 
}; 
+0

反過來,我創建了一個基礎對象數組,並試圖以可變大小的派生對象數組的形式訪問它。我已經意識到這將無法正常工作,並且正在嘗試制定一系列基類指針的語法。我會檢查你發佈的鏈接,看起來很有幫助。 – ihtkwot 2009-11-19 05:53:58

+0

在這種情況下,會發生對象切片(假設您將它作爲對象存儲在數組中),並且數組中的所有對象實際上都是基類對象。您不能將其轉換爲派生類對象並嘗試使用它。 – Naveen 2009-11-19 05:58:20

相關問題