我定义了一个班级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;
}
答案 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;
这是怎么回事:
您构建temp
信号:
信号温度(3,25,9);
创建内部数组
sig_Data = new complex [22];
你的循环看起来像这样
表示(i = 3; i <25; ++ i)
对于i
operator[]
,{<1}}执行此操作
if(i&gt; = range_start&amp;&amp; i&lt; = range_end)返回sig_Data [9 + i];
现在想象一下i = 15
的一个步骤,它会做到这一点
返回sig_Data [9 + 15];
违反了未定义行为的数组边界。
现在,我会留给你解决这个烂摊子。
PS
好吧,你有内存泄漏,你永远不会delete[] sig_Data
。即使你这样做,你也会遇到堆腐败,因为你在拷贝构造函数中做了一个浅拷贝