-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 时,添加似乎在这里正确发生。我什至尝试使用带有复制交换成语的赋值重载(什么是复制交换成语)。

函数中使用的构造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

好的,让我在心里为你调试你的代码

想象一下你有两个信号

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; i < 25; ++i)

  4. 对于每一个ioperator[]这样做

    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 回答