30/09/2018, 18:17
Lại là operator=
Có vẻ mình vẫn chưa luyện tới đỉnh cái operator= này, mời mọi người xem thử và giải đáp giúp:
class Node {
public:
int data;
Node* next;
Node() {
data = 0;
next = NULL;
}
Node(int data) {
this->data = data;
this->next = NULL;
}
};
class CList {
private:
int count;
Node* pHead;
public:
CList() {
count = 0;
pHead = NULL;
}
~CList() {
count = 0;
Node*pTemp = this->pHead;
while (pHead) {
pHead = pHead->next;
delete pTemp;
pTemp = pHead;
}
}
CList(const CList& x) {
Node* pTemp2 = x.pHead;
while (pTemp2) {
Node* pTemp1 = new Node();
pTemp1->data = pTemp2->data;
if (this->pHead == NULL) {
this->pHead = pTemp1;
}
else {
Node* pPos = this->pHead;
while (pPos->next != NULL) {
pPos = pPos->next;
}
pPos->next = pTemp1;
}
pTemp2 = pTemp2->next;
}
this->count = x.count;
}
//Gán LinkedList
CList& operator=(const CList& x) {
if (this->pHead) {
Node*pTemp = this->pHead;
while (this->pHead) {
this->pHead = this->pHead->next;
delete pTemp;
pTemp = this->pHead;
}
}
Node* pTemp2 = x.pHead;
while (pTemp2) {
Node* pTemp1 = new Node();
pTemp1->data = pTemp2->data;
if (this->pHead == NULL) {
this->pHead = pTemp1;
}
else {
Node* pPos = this->pHead;
while (pPos->next != NULL) {
pPos = pPos->next;
}
pPos->next = pTemp1;
}
pTemp2 = pTemp2->next;
}
this->count = x.count;
return *this;
}
//Cộng 2 LinkedList
CList operator+(const CList& x) {
CList re = *this;
re.count += x.count;
Node* pTemp = re.pHead;
while (pTemp->next) {
pTemp = pTemp->next;
}
pTemp->next = x.pHead;
return re;
}
};
Ở hàm main mình cho CList c = a + b thì nó báo lỗi valid heap pointer, mình nghĩ mình nó bị sai ở chỗ operator = và copy constructor (tuy nhiên mình test trường hợp cho CList c = a thì chạy ngon lành không văng lỗi gì cả)…
Bài liên quan
trong operator+
pTemp->next = x.pHead;
ko thể viết tắt như vậy được, phải copy từng phần tử trong
x
. Nếu viết tắt như vậy thìc = a + b;
thì (a+b) sau khi được gán vào c sẽ được giải phóng, mà viết tắt như vậy thì nó giải phóng luôn b (a vẫn an toàn vì có
re
copy). Tới khi giải phóng b thì gặp lỗi đã giải phóng rồi, giải phóng lần nữa là sai.Vẫn còn lỗi :’(
pTemp->next = pTemp2;
gán kiểu vậy cũng là gán về phần tử nằm trongx
. Phảinew
ra hẳn phần tử mới luônko muốn
new
thì có thể xài copy của x chứ ko phải chính x (tham trị thay vì tham chiếu)trong code ban đầu sửa có 1 dòng và thêm 1 dòng thôi =)
cả operator= nữa, xài copy-and-swap luôn, truyền tham trị
CList x
, swapcount
vàpHead
6 dòng là xong rồiMình chưa hiểu lắm đoạn không delete this vì có re copy :v có phải là sau khi ra khỏi phương thức thì các đối tượng gồm this và tham số truyền vào đều sẽ bị delete?
vì khi viết
c = a + b;
thì toàn bộ vế phải của phép gán, hay a + b, là 1 object riêng biệt (object được trả về từ operator+). Khi gán object này cho c xong rồi thì nó sẽ được giải phóng. Nếu ko copy
*this
ra riêng thì mấy phần tử trong dslk mà this trỏ tới lại được thêm object (a+b) nắm quyền giải phóng nữa, thành ra cuối cùng nó sẽ bị giải phóng 2 lần. Dslk màthis
trỏ tới ko bị giải phóng ngay sau operator+ mà được giải phóng khi nào phạm vị (scope) của nó kết thúc. Ở đây a + b thìthis
là con trỏ tới a, mà phạm vi của a là nằm trong thân hàm main, nên khi nào main kết thúc thì a mới được giải phóng.mà nếu ko copy ra
re
riêng thìa
cũng bị thay đổi rồi.CList operator+(CList x)const
thêm chữ const sau phương thức này để bảo đảm this->pHead và this->n ko bị thay đổi. Nhưng dslk mà this trỏ tới vẫn thay đổi được thì phải?
Cám ơn nhé, hôm qua tới giờ ngộ ra được 1 mớ chân lí rồi…
Nhưng ở chỗ này:
Nếu có constructor copy thì x lúc này là 1 list riêng không dính gì tới b, pHead của x khác với pHead của b thì đâu cần phải x.pHead = NULL đúng không nhỉ
À mà thôi, lên lớp làm bài tập thầy chỉ cho rồi :v