我需要帮助,因为我一直在努力解决这个问题,但我真的不知道该怎么做。问题是我做了一个复制构造函数;它复制得很好,但是当我想通过在末尾添加元素来修改副本时它不起作用,则不会打印元素。
当我在开头添加元素时,当我尝试使用方法add_at
添加元素时,它会起作用,它会在两个列表中添加元素。我真的不知道问题出在哪里;它是在构造函数中还是在方法中?
你可以认为我的代码很奇怪,但我不得不像这样添加方法......
以下是代码:
.h文件
class CList
{
SElement* first;
SElement* last;
int lenght;
int value;
public:
CList();
CList(CList const& clist);
~CList();
// add methods
void add(int value);
void add_first(int value);
void add_at(int at, int value);
void addObject(void* object);
void addObject_first(void* object);
void addObject_at(int at, void* object);
// delete methods
void del_last();
void del_first();
void del_index(int index);
void del_element(void* value);
void del_ielement(int& value);
// getery
int iget_lenght();
int iget_element(int const index);
SElement* sget_element(int index);
void* get_element(int index);
void set_element(int const index, int& value);
void pop();
void push(int value);
void printCList();
private:
void priv_push(int & value);
};
.cpp
中涉及的方法CList::CList()
{
first = new SElement;
last = new SElement;
first = last = NULL;
lenght = 0;
value = 0;
}
CList::CList(CList const& clistcopy)
{
this->lenght = clistcopy.lenght;
this->value = clistcopy.value;
first = new SElement;
last = new SElement;
// pointer = last = NULL;
*first = *clistcopy.first;
*last = *clistcopy.last;
}
CList::~CList()
{
SElement* el;
while (first)
{
el = first->next;
delete first;
first = el;
}
delete last;
}
// ADD FIRST
void CList::addObject_first(void* object)
{
SElement* el = new SElement;
el->next = first;
el->previous = NULL;
el->object = object;
if (first != NULL)
first->previous = el;
first = el;
if (!last) last = first;
lenght++;
}
void CList::add_first(int wartosc)
{
value = wartosc;
int* wsk = &value;
int* pnt = new int;
*pnt = *wsk;
addObject_first(pnt);
}
// ADD LAST
void CList::addObject(void* object)
{
if (!last)
{
SElement* el = new SElement;
el->object = object;
el->next = NULL;
el->previous = NULL;
first = last = el;
}
else
{
SElement* el = last;
el->next = new SElement;
el = el->next;
el->next = NULL;
el->previous = last;
el->object = object;
last = el;
el = NULL;
}
}
void CList::add(int wartosc)
{
value = wartosc;
int* wsko = &value;
int* pnt = new int;
*pnt = *wsko;
addObject(pnt);
}
// ADD AT
void CList::addObject_at(int index, void* value)
{
SElement* el2 = new SElement;
if (index - 1 == 0)
addObject_first(value);
else if (index - 1 == lenght)
addObject(value);
else if (index < 0 || index > lenght)
cout << "blad : nie mozesz dodac na indeks poza lista" << endl;
else
{
SElement* el = sget_element(index - 1);
el2->next = el->next;
el2->previous = el;
el2->object = value;
el->next = el2;
el->next->previous = el2;
if (!(el2->next)) last = el2;
lenght++;
}
}
void CList::add_at(int at, int wartosc)
{
value = wartosc;
int* wsko = &value;
int* pnt = new int;
*pnt = *wsko;
addObject_at(at, pnt);
}
void CList::printCList()
{
if (first == NULL)
cout << "Lista jest pusta" << endl;
else
{
SElement* el;
el = first;
while (el->next != NULL)
{
cout << el->get_value();
cout << " ";
el = el->next;
}
cout << el->get_value();
}
cout << endl;
}
主要
int main()
{
CList list = CList();
list.add_first(1);
list.add_first(0);
list.add_first(2);
list.add_first(4);
list.add(5);
list.add(10);
CList list2 = CList(list);
list.printCList();
list2.printCList();
list2.add(100);
list2.add(150);
cout << list.iget_lenght() << endl;
cout << list2.iget_lenght() << endl;
list.printCList();
list2.printCList();
system("pause");
return 0;
}
答案 0 :(得分:0)
在我看来,在尝试查明问题之前,您应该清理代码。
例如:
CList::CList()
{
first = new SElement; // <-- these two lines
last = new SElement; // <-- are useless
first = last = NULL;
lenght = 0;
value = 0;
}
此外,复制构造函数的语义错误。在这里,您只需复制头部和尾部指针,但不要复制列表中的对象。 更确切地说,你似乎试图复制它们,但你的代码也是错误的:
first = new SElement; // allocate an SElement
*first = *clistcopy.first; // copy model's element into it
// since you don't assign first to a permanent variable, it is lost forever
无论如何,即使使用正确的头/尾副本,您的副本仍会引用存储在模型中的对象
修改“副本”也会改变原始列表的元素,这是完全错误的
此外,由于length
和value
字段确实是重复的,因此只要修改了列表中的任何一个,它们就会与链接元素的状态不一致。
要制作真正的复制构造函数,您需要浏览列表并复制每个元素。 例如:
CList::CList(CList const& clistcopy)
{
// create an empty list
this->lenght = 0;
this->value = 0;
this->first = this->last = NULL;
// browse through all elements of the model
for (SElement * elt = clistcopy->first ; elt != NULL ; elt = elt->next)
{
// create a copy of each element
elt_copy = new SElement (elt);
// and insert it into the copy of the list
this->add (elt_copy);
}
}
编辑:这只是伪C ++来说明原理。我怀疑它甚至会在其复杂状态下编译。
我不知道这是否足以解决您的所有问题,但这肯定会从您的复制构造函数中删除一个主要的设计缺陷。
答案 1 :(得分:0)
There are deep copies and shallow copies.你已经做了一些介于两者之间的东西,并且有两者的缺点。
在深层副本中(这似乎是您的想法),将复制整个链接列表。
在浅拷贝中,只复制列表中的指针,这样两个CList就可以共享一个链表。
在您的版本中,您复制第一个和最后一个元素(鲁莽地假设它们存在)并分享其余元素。
阅读复制链表,并实施深层复制。