为 c++ 类重载 operator+。
Posted
技术标签:
【中文标题】为 c++ 类重载 operator+。【英文标题】:Overloading operator+ for c++ class. 【发布时间】:2012-05-03 12:56:22 【问题描述】:我正在尝试为我的类实现 operator+(它必须连接来自同一类的两个对象的单链表),但程序给出错误:“lab5.exe 中 0x01351ca3 处的未处理异常:0xC0000005:访问冲突读取位置 0xcccccccc。” 奇怪的是它正确连接,因为我在 operator+ 中返回 temp 之前正在检查它(通过 //temp.print();)。
如果您能解释一下我的错误在哪里,我将不胜感激。代码如下:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class list
struct lista
int num;
char* word;
lista* next;
;
lista* head;
char* name;
public:
list(char* name1)head=NULL;name=new char[strlen(name1)+1];strcpy(name,name1);
char getChar(int key, int index);
void setChar(int key, int index, char c);
void insert(int number,char* txt);
void remove(int number);
void print();
list(const list &o);
list& operator=(const list &x);
list& operator+(list &x);
~list();
;
void list::insert(int number,char* txt)
lista* ptr,*tmp;
ptr=head;
lista* newlista=new lista;
newlista->num=number;
newlista->next=NULL;
newlista->word= new char[strlen(txt)+1];
strcpy(newlista->word,txt);
if(head==NULL)
head=newlista;
newlista->next=NULL;
else while(ptr!=NULL)
if(strcmp(txt,ptr->word)>=0)
if(ptr->next!=NULL && strcmp(txt,ptr->next->word)<=0)
tmp=ptr->next;
ptr->next=newlista;
newlista->next=tmp;
break;
else if(ptr->next!=NULL && strcmp(txt,ptr->next->word)>0)
ptr=ptr->next;
else
//next is empty
ptr->next=newlista;
break;
else
//txt less than in 1st element
newlista->next=head;
head=newlista;
break;
return;
void list::print()
cout<<name<<";"<<endl;
lista *druk;
druk=head;
while(druk!=NULL)
cout<<"txt: "<<druk->word<<" | "<<"num: "<<druk->num<<endl;
druk=druk->next;
cout<<endl;
return;
void list::remove(int number)
if(head==NULL)
return;
if(head->num==number)
lista* ptr=head;
head=head->next;
delete [] ptr->word;
delete ptr;
return;
lista* ptr=head;
while(ptr->next!=NULL && ptr->next->num!=number)
ptr=ptr->next;
if(ptr->next==NULL)
cout<<number<<" element not found"<<endl;
return;
lista* todelete=ptr->next;
ptr->next=todelete->next;
delete [] todelete->word;
delete todelete;
return;
list::list(const list &o)
lista *xtr = o.head;
head=NULL;// without it doesn't work.
lista *etr=head;// set etr on head?
while (xtr)
lista* ntr = new lista;
if (!ntr)
cerr << "list::CopyConstructor: Allocation memory failure!";
cerr << endl;
break;
ntr->num = xtr->num;
ntr->word= new char[strlen(xtr->word)+1];
strcpy(ntr->word,xtr->word);
ntr->next = NULL;
if (head)
etr->next = ntr;
else
head = ntr;
etr = ntr; // keep track of the last element in *this
xtr = xtr->next;
name = new char[strlen(o.name)+5];
strcpy(name,o.name);
strcat(name,"Copy");
list& list::operator=(const list &x)
if(this==&x)
return *this;
lista *etr=head;
while(etr) // removing list from this
etr=etr->next;
delete head;
head=etr;
lista *xtr=x.head;
while(xtr)
int copied=xtr->num;
lista *ntr= new lista;
ntr->word=new char[strlen(xtr->word)+1];
if (!ntr)
cerr << "list::operator=: Allocation memory failure!" << endl;
break;
ntr->num=copied;
strcpy(ntr->word,xtr->word);
ntr->next=NULL;
if (!head)
head = ntr;
else
etr->next = ntr;
etr = ntr; // keep track of the last element in *this
xtr = xtr->next;
char *name=new char[strlen(x.name)+1];
strcpy(name,x.name);
return *this;
list::~list()
cout<<"Object with name:"<<name<<" destroyed!"<<endl;
delete [] name;
lista *dtr=head;
while(dtr) // removing lista from this
dtr=dtr->next;
delete [] head->word;
delete head;
head=dtr;
list& list::operator+(list &x)
list temp(this->name);
temp=*this;// using previously made operator= which creates the deep copy of singly linked list from this into temp;
lista *xtr=x.head;
while(xtr)
temp.insert(xtr->num,xtr->word);
xtr=xtr->next;
//temp.print();
return temp;
int main()
list l1("lista1");
l1.insert(5,"Endian");
l1.insert(7,"Endianness");
l1.insert(100,"Hexediting");
l1.insert(34,".mil");
l1.print();
list l2(l1); // usage of CC - the same as list l2=l1;
l2.print();
l2.remove(5);
l2.print();
l1.print();
list l3("asajnment");
l3=l2=l1;
l3.print();
list l4("Testing+");
l4.insert(155,"+++++++");
l4.insert(144,"-----");
l4.insert(111,"lalala");
l4.print();
l1=l4+l3;
l1.print();
getchar();
return 0;
【问题讨论】:
恕我直言,有 operator+ 很奇怪,它返回 list&。语义上它类似于 operator+=,它应该修改它的 lhs。最好改名字,或者有list operator+,构造新对象。 Sample code 应该完整而简洁——足以重现问题,但仅此而已。发布的示例包含过多的无关代码。 【参考方案1】:我认为你不应该在你的 operator+ 中返回一个引用
list list::operator+(list &x)
list temp(this->name);
temp=*this;// using previously made operator= which creates the deep copy of singly linked list from this into temp;
lista *xtr=x.head;
while(xtr)
temp.insert(xtr->num,xtr->word);
xtr=xtr->next;
//temp.print();
return temp;
如果您想返回评论中提到的链接参考:
list& list::operator+(list &x)
lista *xtr=x.head;
while(xtr)
this->insert(xtr->num,xtr->word);
xtr=xtr->next;
return this;
这会将x
的值连接到您当前的对象。
您的编译器仍然应该警告您正在返回对临时对象的引用。
您还应该开始接受更多的答案,并考虑观众在看到您的帖子时的想法,您认为您发布的内容是否格式正确、信息丰富等?
【讨论】:
我返回引用是为了允许操作符链接,我的意思是a+b+c+d【参考方案2】:您正在返回对临时对象的引用。这是不正确的。
当它被外部代码使用时,被引用的对象已经被销毁了。
【讨论】:
以上是关于为 c++ 类重载 operator+。的主要内容,如果未能解决你的问题,请参考以下文章
[C++] 类与对象(中) 一篇带你解决运算符重载实例--日期类Date
C++ 继承多态关系中的赋值运算符的重载=operator()