2012-02-12 57 views
1

我有一個頭文件中定義這個位置類:瞬態拷貝構造函數的怪事

class E_IndexList { 
public: 
    E_UIntegerList* l; 
    inline void *data() { // retrieve packed data: stride depends on type (range) 
     return l->data(); 
    } 
    inline void insert(unsigned value) { 
     if (value > maxval[l->range]) { 
      promote(); 
      insert(value); 
     } else { 
      l->push_back(value); 
     } 
    } 
    inline size_t size() { 
     return l->size(); 
    } 
    inline unsigned long get(int index) { 
     return l->get(index); 
    } 
    void promote() { 
     if (l->range == E_UIntegerList::e_byte) { 
      E_UShortList *new_short_list = new E_UShortList(*((E_UByteList*)l)); 
      delete l; 
      l = new_short_list; 
     } else if (l->range == E_UIntegerList::e_short) { 
      E_UIntList *new_int_list = new E_UIntList(*((E_UShortList*)l)); 
      delete l; 
      l = new_int_list; 
     } else ASSERT(false); 
    } 
    // start off with bytes by default 
    E_IndexList() { 
     l = new E_UByteList; 
    } 
    E_IndexList(E_UIntegerList::int_bits range) { 
     switch(range) { 
     case E_UIntegerList::e_byte: 
      l = new E_UByteList; 
      break; 
     case E_UIntegerList::e_short: 
      l = new E_UShortList; 
      break; 
     case E_UIntegerList::e_int: 
      l = new E_UIntList; 
      break; 
     default: 
      ASSERT(false); 
      break; 
     } 
    } 
    E_IndexList(const E_IndexList& cpy) { // copy ctor 
     switch(cpy.l->range) { 
     case E_UIntegerList::e_byte: 
      l = new E_UByteList(((E_UByteList*)cpy.l)->list); 
      break; 
     case E_UIntegerList::e_short: 
      l = new E_UShortList(((E_UShortList*)cpy.l)->list); 
      break; 
     case E_UIntegerList::e_int: 
      l = new E_UIntList(((E_UShortList*)cpy.l)->list); 
      break; 
     default: 
      ASSERT(false); 
      break; 
     } 
    } 
    ~E_IndexList() { 
     delete l; 
    } 
}; 

這裏有一些更多的類它利用:

static const unsigned long maxval[] = {0xff,0xffff,0xffffffff}; 
class E_UIntegerList { 
public: 
    enum int_bits {e_byte = 0, e_short = 1, e_int = 2}; 
    virtual ~E_UIntegerList() {} 
    int_bits range; 
    virtual void push_back(int i) = 0; 
    virtual void *data() = 0; 
    virtual size_t size() = 0; 
    virtual unsigned long get(int index) = 0; 
}; 
struct E_UByteList:public E_UIntegerList { 
    std::vector<unsigned char> list; 
    E_UByteList() { 
     range = e_byte; 
    } 
    E_UByteList(const std::vector<unsigned char>& copy) { 
     list = copy; 
    } 
    inline void push_back(int i) { 
     list.push_back(i); 
    } 
    inline void *data() { return list.data(); } 
    inline size_t size() { return list.size(); } 
    inline unsigned long get(int index) { return list[index]; } 
}; 
struct E_UShortList:public E_UIntegerList { 
    std::vector<unsigned short> list; 
    E_UShortList() { 
     range = e_short; 
    } 
    E_UShortList(const std::vector<unsigned short>& copy) { 
     list = copy; 
    } 
    E_UShortList(const E_UByteList& promotee) { 
     range = e_short; 
     list.assign(promotee.list.begin(),promotee.list.end()); // assignment should be compatible 
    } 
    inline void push_back(int i) { 
     list.push_back(i); 
    } 
    inline void *data() { return list.data(); } 
    inline size_t size() { return list.size(); } 
    inline unsigned long get(int index) { return list[index]; } 
}; 
struct E_UIntList:public E_UIntegerList { 
    std::vector<unsigned int> list; 
    E_UIntList() { 
     range = e_int; 
    } 
    E_UIntList(const std::vector<unsigned int>& copy) { 
     list = copy; 
    } 
    E_UIntList(const E_UShortList& promotee) { 
     range = e_int; 
     list.assign(promotee.list.begin(),promotee.list.end()); 
    } 
    inline void push_back(int i) { 
     list.push_back(i); 
    } 
    inline void *data() { return list.data(); } 
    inline size_t size() { return list.size(); } 
    inline unsigned long get(int index) { return list[index]; } 
}; 

現在,我使用的方式這個類是我有一個std::vector<E_IndexList>,我用作索引列表的容器。

奇怪的行爲是,當我運行該程序有時它沒有問題,有時它斷言錯誤。

所以這對我來說是一個很大的紅旗,因爲超級魚腥味正在發生。我很可能最終放棄了整個E_IndexList,直到我開始研究遊戲網絡代碼,這是一個很長的路要走。但是,我想知道這裏發生了什麼。

我已經把範圍設置爲E_UIntegerList中枚舉的有效值,那麼這個斷言怎麼會被觸發?我不能開始解釋爲什麼行爲不一致。調用此代碼的測試不是多線程的。

+0

哪個斷言觸發? (我只是在'推廣'中投注一個,因爲。) – Mat 2012-02-12 20:48:56

+0

¤一些構造函數不設置'range'成員。例如。 'E_UShortList(const std :: vector &copy)'不。無論如何,這是**過早優化**的一個極端情況,所以它是否真的有問題,如果有其他錯誤:只是廢棄這個代碼。使用'std :: vector '。例如。乾杯&hth。, – 2012-02-12 20:55:08

回答

1

你的構造像這樣的:

E_UByteList(const std::vector<unsigned char>& copy) { 
    list = copy; 
} 

不初始化range從父E_UIntegerList類。

+0

+1反擊匿名白癡downvoter。 – 2012-02-13 00:34:50

3

您的E_UByteList來自向量構造函數不會設置range值。

整個設計有點毛糙;你應該學習如何使用構造函數初始化列表,並且我可能會給基類賦予一個受保護的構造函數,該構造函數設置range的值,並且可以從派生構造函數的初始值設定項中調用它。