2009-09-07 28 views
6

我的應用程序使用了大量的Panda對象。每個Panda都有一個Bamboo對象的列表。此列表在Panda初始化後不會更改(不添加或刪除Bamboo對象)。目前,如下班裏實現:變長對象:永遠是個好主意?

class Panda 
{ 
    int a; 
    int b; 
    int _bambooCount; 
    Bamboo* _bamboo; 

    Panda (int count, Bamboo* bamboo) 
    { 
    _bambooCount = count; 
    _bamboo = new Bamboo[count]; 

    // ... copy bamboo into the array ... 
    } 
} 

爲了緩解分配Bamboo對象的數組的開銷,我可以按如下方式實現這個類 - 基本上,而不是通過常規的構造函數創建對象,建築方法分配一個內存塊同時按住Panda對象及其Bamboo陣列:

class Panda 
{ 
    int a; 
    int b; 

    Panda() 
    { 
     // ... other initializations here ... 
    } 

    static Panda *createPanda (int count, Bamboo* bamboo) 
    { 
    byte* p = new byte[sizeof(Panda) + 
     sizeof(Bamboo) * count]; 
    new (p) Panda(); 

    Bamboo* bamboo = (Bamboo*) 
     p + sizeof(Panda); 

    // ... copy bamboo objects into the memory 
     // behind the object... 

     return (Panda*)p; 
    } 
} 

你可以預見與第二設計任何問題,除了增加的維護工作等?這是一個可接受的設計模式,或者只是一個過早的優化,可能會在稍後回來咬我?

+0

它會咬人。它會咬人。 – 2009-09-07 17:03:44

+1

你打破了C++中大多數類類型的語義。 C++中不存在可變長度的對象。 – jalf 2009-09-07 17:30:54

+2

如果您對這種令人eye目的黑客感興趣,您可能還想看看Symbian/C++中的TBuf8和TBuf16類模板。 – 2009-09-07 18:45:50

回答

9

C++爲您提供了另一種選擇。你應該考慮使用std :: vector。

class Panda 
{ 
    int a; 
    int b; 
    std::vector<Bamboo> bamboo; 
    // if you do not want to store by value: 
    //std::vector< shared_ptr<Bamboo> > bamboo; 

    Panda (int count, Bamboo* bamb) : bamboo(bamb, bamb+count) {} 
} 

如果你想存儲熊貓和竹子在連續的內存,你可以使用的解決方案,從this article。主要想法是超載operator newoperator delete

+0

你必須意識到這種類型的解決方案的副作用和你將不得不處理的問題:用戶將無法使用容器內的對象(特別是std :: vector,它預先分配內存基於傳入的類型)這種欺騙最終會以不僅難以維護(提問者知道)但不自然的代碼使用 – 2009-09-07 18:09:13

+0

最自然的是使用'std :: vector'。所有其他解決方案的使用非常有限,應謹慎應用。 – 2009-09-07 18:42:25

+0

如果我沒有弄錯GCC的字符串實現使用這種欺騙。訣竅是Panda對象可能包含一個指向(過度分配)實現類的單個指針。 – UncleBens 2009-09-07 18:42:53

1

您使用新操作符的「新」外觀。相對Panda完全正確,但爲什麼不使用Bamboo初始化程序?

4

如果有人值得購買熊貓,你會被咬

//compiler allocates 16-bytes on the stack for this local variable 
Panda panda = *createPanda(15, bamboo); 

這是可以接受的(但很可能是過早的和可怕的優化),如果你永遠只能是指事物由指針和從來沒有價值,如果你要小心拷貝構造函數和賦值操作符。

3

根據我的經驗,過早優化總是「不成熟」。也就是說,您應該剖析代碼並確定是否需要優化,或者您只是爲自己創建更多工作長跑。

另外,在我看來,優化是否值得與否的問題很大程度上取決於Bamboo類的大小和每個熊貓的平均數量。

3

這是發現在C.
但在C++中沒有真正的需要。

真正的問題是你爲什麼要這樣做?

這是一個不成熟的優化,只需在內部使用std :: vector <>,所有問題都會消失。

由於您使用的是原始指針內部的階級擁有你需要重寫的默認版本:

  • 默認構造
  • 析構函數
  • 拷貝構造函數
  • 賦值運算符
7

我們如何說服人們在編程簡單簡而言之:數學家稱之爲「優雅」 - 不是可有可無的奢侈品,而是決定成功與失敗之間的關鍵問題?

- 艾茲赫爾·戴克斯特拉

+0

只是不。許多事情可能會出錯......你將如何實現複製構造函數,賦值,析構函數?你打算如何處理想要擁有熊貓陣列的用戶? – 2009-09-07 17:04:47

+0

數學家不知道編程和現實世界。 – Lothar 2017-01-30 15:35:38

2

如果你是絕望的,你也許可以做這樣的事情:

template<std::size_t N> 
class Panda_with_bamboo : public Panda_without_bamboo 
{ 
    int a; 
    int b; 
    Bamboo bamboo[N]; 
} 

但我相信你不是絕望,而是過早地優化。

相關問題