使用数组订阅运算符

时间:2012-11-30 13:34:52

标签: c++ variable-assignment operator-keyword

我定义了一个班级complex和班级signal。 我有重载+和 - 复杂的类。 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时,这里的添加似乎正确发生。 我甚至尝试使用复制交换习惯用法(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;
}

2 个答案:

答案 0 :(得分: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[]结果的赋值会在表达式的末尾被丢弃。

答案 1 :(得分:0)

好的,让我为你精神调试你的代码

想象你有两个信号

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

现在你要添加

signal s = s1 + s2;

这是怎么回事:

  1. 您构建temp信号:

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

  2. 创建内部数组

    sig_Data = new complex [22];

  3. 你的循环看起来像这样

    表示(i = 3; i <25; ++ i)

  4. 对于i operator[],{<1}}执行此操作

    if(i&gt; = range_start&amp;&amp; i&lt; = range_end)返回sig_Data [9 + i];

  5. 现在想象一下i = 15的一个步骤,它会做到这一点

    返回sig_Data [9 + 15];

  6. 违反了未定义行为的数组边界。

    现在,我会留给你解决这个烂摊子。

    PS 好吧,你有内存泄漏,你永远不会delete[] sig_Data。即使你这样做,你也会遇到堆腐败,因为你在拷贝构造函数中做了一个浅拷贝