2011-10-06 244 views
0

我正在開發一個項目,其中我使用了許多類。 創建類的我已經使用了新的運營商......例如,在香蕉類我有蘋果類的實例變量......減少內存使用量

這是我想說的&按比例縮小的陳述並不代表編碼字 - 字......所以,請不要點語法錯誤......但要儘量理解頭文件的方法

(banana.h):

static int counter = 0; 
class banana 
{ 
    public: 
    apples *ap_obj;//(apple is a class defined another file apples.cpp) 
    int *index; 
} 

in banana.cpp:

class banana 
{ 
    banana::banana(void) 
    { 
    ap_obj = new apples; 
    index = new int; 
    *index = ++counter; 
    } 
}; 

我的第一個問題是,我的方法在記憶效率方面是否正確? (我知道我沒有任何運行時錯誤肯定)

我的第二個問題是,我想訪問一個香蕉對象在我的任何類的方法之一,通過使用索引(請注意,每香蕉對象具有唯一索引)變量。 爲此,我想使用另一個類的註冊表(因爲我想存儲許多類的對象的索引)。 我想存儲任何類的第一個對象的指針在我的註冊表類中。 &用於訪問類的任何第n個對象的指針,我打算使用索引變量的第一對象上使用指針arithmatics ...例如

class registry 
{ 
    banana *base_obj;//this value will be initialised when i create the 1st object of banana class 
    banana *registry::get_nth_object(int shift); 
    { 
    return *(base_obj + shift);//shift is the index variable of banana class 
    } 
}; 

在任何其他類別i可以只調用get_nth_object &傳遞我想要的指針對象的索引號&我會得到那一點。

我的代碼有什麼問題嗎? 或者如果有什麼可以改善,請幫助我。

供參考我使用http://www.cplusplus.com。 我是一個機甲ENGG學生,所以請原諒我,如果我做任何愚蠢的錯誤

+2

您可以通過使用矢量而不是數組/指針來改善它。 – RvdK

回答

0

首先,你應該找出你的香蕉 - >蘋果關係是什麼樣的關係。如果它是一種作品(一種香蕉由蘋果和...組成),最簡單的想法是將一個蘋果實例存放在香蕉中。

class banana 
{ 
    apple apple_; // a banana HAS A apple 
}; 

如果這是真的,但你必須香蕉無數並有一個數字,一個平等的,你可以實現Flyweight Pattern安全存儲器使用的蘋果。但是你不應該這樣做,因爲你認爲你有一個記憶問題,但是因爲你測量出你有一個蘋果記憶問題。

如果您的關係更多是共享所有權,您應該在香蕉中存儲一個指向Apple實例的指針,並考慮在哪裏存儲蘋果對象。最簡單的方法是存儲std::shared_ptr<apple>並讓參考計數器控制蘋果的使用壽命。

第二個問題是如何存儲和訪問香蕉物體。我會介紹一個BananaRepository,它負責存儲和檢索香蕉。

class BananaRepository 
{ 
    typedef XYZType BananaID; 
    Banana& GetByID(BananaID id); 
    BananaID Add(Banana& b); 
}; 

您應該抽象使用的ID和存儲類型,以便客戶端代碼不依賴於該詳細信息。每個香蕉都有一個ID,我可以使用這個ID從存儲庫中獲得一個香蕉。最簡單的實現是Banana :: ID = vector :: size_type和BananaRepository中的一個向量。

class BananaRepository 
{ 
public: 
    typedef std::vector<Banana>::size_type BananaID; 

    Banana& GetByID(BananaID id) 
    { 
    return bananas_.at(id); 
    } 

    BananaID Add(Banana& b) 
    { 
    bananas_.push_back(b); 
    return bananas_.size() - 1; 
    } 

private: 
    std::vector<Banana> bananas_; 
}; 
0

我知道,我沒有肯定

那麼任何運行時錯誤,看來你運行時錯誤(或更多)。聲明

int *index; 

index爲未初始化的指針,並

*index = ++counter; 

提出的counter內容到index點(這是完全不確定的地方,這可能是)的地方。當然,這將是一個奇怪的錯誤的原因。

也許你想申報

int index; 

index = ++counter; 

我承擔?

3

直接嵌入的內存更有效的(這樣可以節省你的指針雙方的開銷和一個堆分配,提高訪問的局部性):

class banana 
{ 
    private: 
    apples ap_obj; 
    int index; 
} 

請注意,您在忘記new指數你的原始代碼。我甚至不確定我是否瞭解它的需求。是只有用於找到一個特定的banana?如果是這樣,它應該不是banana的成員。爲什麼還要存儲索引?引用特定實例的常用方法是使用banana*

+0

+1,但你應該解釋他爲什麼:-)它不應該是一個「ipse dixit」:-) :-)(也許​​你應該告訴他,與默認拷貝構造函數有區別,並且需要刪除if他使用了一個指針......並且可能還有許多其他的東西) – xanatos

+0

@xanatos:好點,完成。 – MSalters

+0

是的,我忘了把新的索引。讓我糾正它。 –

0
  1. 對於存儲標量數據,您不需要使用指針。這就是爲什麼int index。指定一些「不可能」的值來知道索引是非法的。

  2. 你的方法get_nth_object是錯誤的。您不能確定所有banana's都分配在一致的內存塊中。因此,您不能使用這種線性地址算法來獲取對象。查找有關使用動態數組或列表的信息。在陣列的情況下,您可能想檢查有關超載訂閱運營商的信息

1

首先,香蕉構造函數本身的語法不正確。它不應該被文本類香蕉包圍{};使用新的堆

第二,分配內存將是你需要做的不夠快。你不應該以任何其他方式做它(即不要使用malloc)。所以你在這方面很好。

至於你的註冊表例如,如果你所有的香蕉實例在連續的內存區域被分配get_nth_object只會工作....東西你沒有,當你使用新分配內存的控制。如果你使用新的香蕉[大小]爲香蕉指針分配內存,那會更好,並且內存將是連續的。

即使你沒有讓他們都經常在內存中間隔,如果你需要刪除一個香蕉?還是兩三個?還是半打?很快你會做一些真正的緊張記錄保持事情的工作。

我自己更喜歡在它的構造函數創建時爲其中的每個香蕉分配一個唯一的ID,並且在香蕉的構造函數中插入一個像地圖這樣的關聯容器(即std :: map)(在代碼中使用#include )。我將使用唯一的ID作爲關鍵字,然後您可以使用指向香蕉的指針作爲值。在香蕉的析構中,我會讓香蕉從註冊表中移除。

你的註冊表將負責所屬關聯容器(即地圖)。