-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++ を使用して値をチェックすると、ここで追加が正しく行われるように見えますが、temp に割り当てられていません。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;
}
4

2 に答える 2

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[]は式の最後で破棄されます。

于 2012-11-30T13:52:37.123 に答える
0

OK、あなたのコードを精神的にデバッグさせてください

2 つの信号があるとします。

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

今、あなたは追加しようとしています

signal s = s1 + s2;

何が起こるかは次のとおりです。

  1. tempシグナルを作成します。

    信号温度 (3、25、9);

  2. 内部配列を作成する

    sig_Data = 新しい複合体 [22];

  3. あなたのループは次のようになります

    for (i = 3; i < 25; ++i)

  4. iあなたoperator[]がこれを行うたびに

    if(i >= range_start && i <= range_end) return sig_Data[9+i];

  5. ここでi = 15、これを行うステップを想像してください

    sig_Data[9+15] を返します。

未定義の動作である配列の境界に違反します。

さて、この混乱を解決するのはあなたに任せます。

PS Besies、メモリリークがありますdelete[] sig_Data。そして、コピーコンストラクターで浅いコピーを行うため、ヒープの破損が発生したとしても

于 2012-11-30T14:11:53.043 に答える