我试图了解运算符重载但遇到了问题。该程序只是意味着两个字符串。我知道还有其他方法可以做到这一点,但我想玩。我收到以下错误:
文件:dbgdek.cpp 行:52 _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse));
我认为这与我使用delete []有关。请帮助我真的卡住了。
#include <iostream>
using namespace std;
class list{
public:
char *value;
int size;
list(int s){size=s; allocmem();};
~list(){delete [] value;};
list operator+(list);
private:
void allocmem(void);
};
void list::allocmem(void){
value=new char[size];
}
list list::operator+(list a)
{
list t(a.size+size);
for (int i=0; i<a.size; i++){
t.value[i]=a.value[i];
}
for (int i=a.size; i<t.size; i++){
t.value[i]=a.value[i-a.size];
}
return t;
}
int main ()
{
list a(2),b(2),c(4);
a.value[0]='a';
b.value[0]='b';
a.value[1]='c';
b.value[1]='d';
c=a+ b;
for (int i=0; i<c.size; i++){
cout<<c.value[i];
}
system("pause");
return 0;
}
请帮忙!
答案 0 :(得分:1)
第一个警告标志:您的类的析构函数执行了一些delete
,但该类没有定义复制构造函数或复制赋值运算符。
请参阅Rule of Three。
在调用临时析构函数时,您可能会意外地制作对象的临时副本并弄乱它们。
答案 1 :(得分:1)
您需要为类定义赋值运算符(list::operator=(list const&)
)和复制构造函数(list::list(list const&)
),以避免在析构函数中重复删除内存。如果您没有定义这些函数,编译器将使用这些函数的默认生成版本,这实际上创建了列表对象的按位副本。这是灾难性的,因为在复制列表实例后,两个实例都将具有相同的指针值,从而导致重复删除。
答案 2 :(得分:0)
你需要做两件事:
您正在operator +()
中传递值。这将传递对象的副本(不是您想要的;您想要传递引用)。但是因为您没有创建复制构造函数,复制的对象将获得默认的成员复制 - 现在2个对象具有相同的指针。第一个删除它很好,第二个对象现在有一个无效的指针。
答案 3 :(得分:0)
为什么不使用char*
而不是直接使用std::string
字符串?然后你不必担心内存管理问题(在这种情况下,由于没有像其他人那样实现复制构造函数而导致双重删除)。在最直接的翻译中,就像:
class list
{
public:
std::string value;
int size;
list(int s){size=s; allocmem();}
~list(){}
list operator+(list);
private:
void allocmem(void);
};
void list::allocmem(void){
value.resize(size);
}
请注意,几乎可以肯定使用string
更好的实现(例如size
可以消失)。此外,您可能不应拥有所有属性public
。