2011-12-19 22 views
2

我寫了一個名爲octed_string的類,沒有析構函數,但它的功能很好,但不能返回任何octs_string類型。關於C++中的析構函數;

請看下面的代碼,告訴我什麼是錯的。

當我刪除它的工作的析構函數! (cout print 12)

任何人都可以幫忙嗎?

class octed_string 
{ 
private: 
    uint8_t *value; 
    size_t length; 
    size_t allocated; 
public: 
    octed_string()//constructor 
     :value(0),length(0),allocated(0) 
    { 

    } 
    void copy(uint8_t *from, uint8_t *to) 
    { 
     for (size_t i = 0; i < length; i++) 
      *to++ = *from++; 
    } 

    void allocate() 
     { 
      if (value == 0) 
      { 
       allocated = STACK_INITIAL_ALLOC; 
       value = new uint8_t[allocated]; 
      } 
      else 
      { 
       // We need to allocate more memory 

       size_t new_allocated = allocated + STACK_CHUNK_ALLOC; 
       uint8_t *new_value = new uint8_t[new_allocated]; 

       // Copy from old stack to new stack 
       copy(value, new_value); 

       // Delete the old value 
       delete [] value; 

       allocated = new_allocated; 
       value = new_value; 
      } 
     } 

    ~octed_string()//destructor 
    { 
     if(value) 
      delete [] value; 
    } 

    friend ostream &operator<<(ostream &_output,const octed_string &_str)//opration overloading for cout 
    { 
     for(int i=0;i<_str.length;i++) 
      _output<<(uchar_t)_str.value[i]; 
     return _output; 
    } 

    void add(uint8_t input)//this function automatically add space to value (new) 
    { 
     if (length == allocated) 
      allocate(); // Allocate more memory 

     value[length++] = _value; 
    } 

    octed_string sub_string(int start,int end)//(this function has a problem with destructor i think because it return octed_string) 
    { 
     octed_string a; 
     for(int i=start;i<end;i++) 
      a.add(a); 
     return a; 
    } 
}; 

void main() 
{ 
    octed_string o; //object 
    o.add(1); 
    o.add(2); 
    o.add(3); 

    cout<<o.sub_string(0,2); //i expect printing 12 but i does not! 
} 

----------------------- //回答 感謝phresnel加入以下代碼修復它:

octed_string(const octed_string &_input) 
    :value(0),length(0),allocated(0) 
{ 
    while(length<_input.length) 
    { 
     this->add((uchar_t)_input[length]); 
    } 
} 

octed_string& octed_string::operator= (octed_string const& _in) 
{ 
    octed_string tmp(_in); 
    return *this; 
} 

但我仍然不明白原因。任何機構可以提供任何參考來了解這個問題?

+0

我認爲你需要準確顯示add()中的內容,因爲問題可能在那裏。 – Julian 2011-12-19 11:33:11

+0

你似乎錯過了最重要的代碼:'add'方法。 – 2011-12-19 11:33:18

+0

這實際上是你所有的代碼嗎?你的add函數什麼都不做。 – 2011-12-19 11:33:34

回答

11

您需要爲octed_string定義複製構造函數和賦值運算符。

如果沒有析構函數,它將起作用,因爲爲成員變量value分配的內存不會被銷燬,並且由默認拷貝構造函數構造的拷貝引用與原始的,現在銷燬的對象所做的相同的未刪除內存。

當你有一個析構函數時,內存被刪除。

副本在sub_string()返回時創建。

+1

這還不夠。他還必須有良好的複製任務。 – 2011-12-19 11:38:08

+0

@ phresnel,正確。更新。 – hmjd 2011-12-19 11:39:44

1

可能的原因:

  • 錯字:你已宣佈sub_string,但不sub_stirng
  • 缺少執行:
    • 應該把它分配的東西你add()功能是空的?
  • 你不是已經精心設計的拷貝構造和拷貝賦值:
    • 當你的字符串對象圍繞複製,其中一個副本將delete值緩衝區
  • 失蹤分配您的value緩衝區。
    • 您不必在所有
  • 其他分配的內存爲您value -buffer。

如果沒有實際的代碼,更好的答案是不可能的。

1

你想達到什麼目的?這是使用std :: string無法實現的任何東西嗎?

幾條評論:

1您是如何在內部添加新值的?

2前綴下劃線(_output)區一個壞主意

3,您需要定義一個拷貝構造函數如:

// Assuming value is an array 
octed_string::octed_string(const octed_string& rhs) 
    : value(rhs.value ? new uint8_t[ rhs.length ] : 0) 
    , length(rhs.length) 
    , allocated(rhs.allocated) 
{ 
} 

4您還需要一個賦值運算符

octed_string& octed_string::operator= (octed_string const& f) 
{ 
    octed_string tmp(f); 
    std::swap(tmp, *this); 
    return *this; 
} 
0

任何具有類型指針成員變量的類,需要一個拷貝構造函數,重載的operator =和析構函數。

考慮下面的代碼:

octed_string str1; // suppose this is initialized as desired 

octed_string str2 = str1; 

在第二行中,編譯器生成的拷貝構造函數被調用,該複製件一個接一個。這裏我們有一個名爲value的char_t *成員。所以,str2的值指向str1的相同內存位置。這被稱爲淺拷貝。在這種情況下,str1和str2共享相同的內存位置值,如果str1超出範圍,將導致懸掛指針。以下代碼顯示了此事實的一種可能情況:

octed_string test() { 
    octed_string str; 
    // Initialize str... 
    return str; 
} 

同樣的故事適用於對象的分配。