2012-11-30 67 views
-1

我有一個類complex和類signal定義。 我已經重載+和 - 複雜的類。 信號類被定義複雜類型complex *sig_Data;的成員,我已經使用陣列訂閱信號如下陣列訂閱運營商的使用

complex &operator[](int i) 
    { 
     if(i >= range_start && i <= range_end) return sig_Data[zero_pt+i]; 
     else return complex(0); 
    } 

zero_pt被用作參考。

爲+信號類的運算符重載我已經使用這個

signal operator+(signal &a, signal &b) 
{ 
    int r_start = min(a.range_start, b.range_start); 
    int r_end = max(a.range_end, b.range_end); 
    int z_pt = max(a.zero_pt, b.zero_pt); 
    signal temp(r_start, r_end, z_pt); 
    for(int i = r_start; i <= r_end; i++) 
    { 
     temp[i] = a[i] + b[i]; 
    } 
    return temp; 
} 

加入似乎當我檢查在調試使用VC++的值,但他們沒有被分配到臨時正確地在這裏發生。 我甚至嘗試使用copy-swap成語的分配超載(What is the copy-swap idiom)。

signal operator[](int i)函數中使用的構造函數是。

signal(int r_start, int r_end, int z_pt) 
    { 
     range_start = r_start; 
     range_end = r_end; 
     zero_pt = z_pt; 
     int arr_ind = r_end - r_start; 

     sig_Data = new complex [arr_ind]; 
    } 

請幫我確定我要出錯的地方。

一個更完整的代碼:

#include <iostream> 
    #include <conio.h> 
    #include <string> 

    #include <cstdlib> 
    #include <cctype> 
    #include <cstring> 


    using namespace std; 


    namespace Complex 
    { 
     class complex 
     { 
      double real; 
      double imag; 

     public: 
      complex(double re = 0, double im = 0) 
      { 
       real = re; 
       imag = im; 
      } 

      complex(complex &t) 
      { 
       real = t.real; 
       imag = t.imag; 
      } 

      void StrtoComplex(const char *temp) 
      { 
       int i; 

       for(i = 0; i < strlen(temp); i++) 
       { 
        if(temp[i] == 'j' || temp[i] == 'i') 
         break; 
       } 

       real = atof(temp);//takes till the last valid char so after + or whitespace it ignores 
       if(*(temp + i - 1) == '-') 
        imag = -atof(temp + i + 1); 
       else 
        imag = atof(temp + i + 1); 

      } 

      friend complex operator+(complex &a, complex &b); 
        friend ostream &operator<<(ostream &s, complex &t); 
      friend istream &operator>>(istream &s, complex &t); 
      }; 
     //overloading + to add complex numbers 
     complex operator +(complex &a, complex &b) 
     { 
      complex t; 
      t.real = a.real + b.real; 
      t.imag = a.imag + b.imag; 
      return(t); 
     } 

     ostream &operator<<(ostream &s, complex &t) 
     { 
      s<<t.real<<" +j"<<t.imag; 
      return s; 
     } 

     istream &operator>>(istream &s, complex &t) 
     { 
      std::string temp; 

      std::getline(s, temp); 
      t.StrtoComplex(temp.c_str()); 
      return s; 
     } 
    } 

    namespace Discrete 
    { 
     using Complex::complex; 
     class signal 
     { 
      complex *sig_Data; 

      int range_start, range_end, zero_pt; 

     public: 
      signal() 
      { 
       sig_Data = NULL; 
       range_start = range_end = zero_pt = 0; 
      } 

      signal(complex i) 
      { 
       sig_Data = new complex(i); 
       range_start = range_end = zero_pt = 0; 
      } 

      signal(int r_start, int r_end, int z_pt) 
      { 
       range_start = r_start; 
       range_end = r_end; 
       zero_pt = z_pt; 
       int arr_ind = r_end - r_start; 

       sig_Data = new complex [arr_ind]; 
      } 

      void StrtoSig(char *temp) 
      { 
       int arr_ind = 0; 
       char *tok; 

       if(!*temp) return; 

       tok = temp; 
       zero_pt = 0; 
       // 
       int flag; 

       for(int i = 0; i < (flag = strlen(temp)); i++) 
       { 
        tok++; 
        if(*tok == '^') zero_pt = arr_ind; 
        if(*tok == ',') arr_ind++; 
       } 
       range_start = 0 - zero_pt; 
       range_end = arr_ind - zero_pt; 

       sig_Data = new complex [arr_ind]; 
       tok = temp+1; 
       for(int i = 0; i <= arr_ind; i++) 
       { 
        if(*tok == ',') tok++; 
        while(isspace(*tok)) tok++; 
        if(*tok == '^') tok++; 
        sig_Data[i].StrtoComplex(tok); 
        while(*tok != ',' && *tok != '}'&& *tok != '\0') tok++; 
       } 
      } 

      complex &operator[](int i) 
      { 
       if(i >= range_start && i <= range_end) return sig_Data[zero_pt+i]; 
       //else return complex(0); 
      } 


      friend signal operator+(signal &a, signal &b); 
        friend ostream &operator<<(ostream &s, signal &t); 
    friend istream &operator>>(istream &s, signal &t); 
     }; 

     //Overloading + operator 
     signal operator+(signal &a, signal &b) 
     { 
      int r_start = min(a.range_start, b.range_start); 
      int r_end = max(a.range_end, b.range_end); 
      int z_pt = max(a.zero_pt, b.zero_pt); 
      signal temp(r_start, r_end, z_pt); 
      for(int i = r_start; i <= r_end; i++) 
      { 
       temp[i] = a[i] + b[i]; 
      } 
      return temp; 
     } 


      ostream &operator<<(ostream &s, signal &t) 
{ 
    s<<"{"; 
    for(int i = t.range_start; i <= t.range_end; i++) 
    { 
     if(i == (t.range_start + t.zero_pt)) 
      s<<" ^"<<t[i]; 
     else if(i == t.range_end) 
      s<<" "<<t[i]; 
     else 
      s<<" "<<t[i]<<","; 
    } 
    s<<"}"; 
    return s; 
} 

     istream &operator>>(istream &s, signal &t) 
     { 
      char *ip; 
      s>>ip; 
      t.StrtoSig(ip); 
      return s; 
     } 
    } 

    void main() 
{ 
    using Discrete::signal; 
    signal a,b,c; 
    a.StrtoSig("{1+i5, ^7+i6}"); 
    b.StrtoSig("{5+i4, 7+i5}"); 

    c = a+b; 
    cout<<c; 
} 
+0

在你的訂閱函數中,當索引超出邊界時,你返回複數(0)。那麼你將如何區分零元素和不正確的索引? – asheeshr

+0

返回對temporaty對象的引用'temp'正在請求麻煩。 'operator +'應該返回一個副本。 – 2012-11-30 13:40:47

+0

@AshRj真的並不重要,因爲我假設信號的值超出此範圍爲零.... – PSK

回答

0

如果你希望能夠通過operator[]修改的類,它必須返回一個參考:當您返回一個值

complex &operator[](int i) 
{ 
    if(i >= range_start && i <= range_end) return sig_Data[zero_pt+i]; 
    else throw std::range_error("invalid index to operator[]"); 
} 

,這是被複制到臨時文件中,因此在表達式末尾將operator[]的結果賦值放棄。

+0

...我做到了這一點,但沒有幫助。另外有人剛剛在這裏建議我不要使用引用.. – PSK

+0

@PSK是關於'運營商+',它應該返回值,而不是引用。 'operator []'應該通過引用返回。 – ecatmur

+0

@PSK:我們沒有說不通過引用返回......我們說不要通過引用返回*本地人*。有一個區別;) –

0

OK,讓我精神上調試代碼爲您

想象,你有兩個信號

signal s1 (5, 20, 8); 
signal s2 (3, 25, 9); 

現在你正試圖添加,然後

signal s = s1 + s2; 

會發生什麼這個:

  1. 您構建了一個temp信號:

    信號溫度(3,25,9);

  2. 哪個創建內部陣列

    sig_Data =新配合物[22]。

  3. 你的循環這個樣子的

    爲(i = 3;我< 25; + +1)

  4. ioperator[]這是否

    如果(I> = RANGE_START & & i < = range_end)return sig_Data [9 + i];

  5. 現在想象一個步驟,其中i = 15,它將爲此

    返回sig_Data [9 + 15];

其中違反了未定義行爲的數組邊界。

現在,我會給你解決這個爛攤子。

PS 別名,你有內存泄漏,你從來沒有delete[] sig_Data。即使你確實會得到一個堆腐敗,因爲你在你的拷貝構造函數中做了一個淺拷貝

+0

我想這是我的錯,但你對我的代碼的理解是錯誤的......我的'range_start'永遠不會大於零,我的'zero_pt'就是計數使得範圍相對於零移位。 ..我會添加一些代碼,以及 – PSK

+0

@PSK,舉兩個信號的例子,你試圖添加哪個重現問題 – 2012-11-30 14:28:38