Giúp em về operator=
Em có xây dựng 1 class về đa thức bên dưới:
#include<iostream>
using namespace std;
class DT {
private:
int bac;
float* ptr;
public:
DT();
~DT();
friend istream& operator>>(istream& is,DT& u);
friend ostream& operator<<(ostream& os,DT& u);
DT& operator=(DT& u);
DT operator+(DT u);
};
DT::~DT() {
delete[] ptr;
}
DT::DT() {
bac=0;
ptr=new float[bac+1];
for(int i=0;i<bac+1;i++)
ptr[i]=0;
}
istream& operator>>(istream& is,DT& u) {
cout<<"Da thuc bac: ";
is>>u.bac;
u.ptr=new float[u.bac+1];
for(int i=0;i<u.bac+1;i++) {
cout<<"Nhap he so thu "<<i<<": ";
is>>u.ptr[i];
}
return is;
}
ostream& operator<<(ostream& os,DT& u) {
for(int i=0;i<u.bac;i++) {
if(u.ptr[i+1]>=0) os<<u.ptr[i]<<"*x^"<<i<<" + ";
else os<<u.ptr[i]<<"*x^"<<i<<" - ";
}
os<<u.ptr[u.bac]<<"*x^"<<u.bac;
return os;
}
DT& DT::operator=(DT &u) {
bac=u.bac;
ptr=new float[bac+1];
for(int i=0;i<bac+1;i++) {
ptr[i]=u.ptr[i];
}
return u;
}
DT DT::operator+(DT u) {
DT temp;
temp.bac=u.bac>bac?u.bac:bac;
temp.ptr=new float[temp.bac+1];
int min=u.bac<bac?u.bac:bac;
for(int i=0;i<min+1;i++) {
temp.ptr[i]=ptr[i]+u.ptr[i];
}
for(int i=min+1;i<temp.bac+1;i++) {
if(min==bac) {
temp.ptr[i]=u.ptr[i];
}
else temp.ptr[i]=ptr[i];
}
return temp;
}
int main() {
DT u,u1,u2;
cout<<"Nhap 2 da thuc: "<<endl;
cin>>u1>>u2;
cout<<"
Da thuc 1:
"<<u1;
cout<<"
Da thuc 2:
"<<u2;
u=u1+u2; //loi
cout<<"
Da thuc tong la:
"<<u1+u2;
}
Nhưng khi đến hàm main em gán u=u1+u2 thì không gán được mong mọi người chỉ giúp.
Em có thử để hàm operator+ trả về tham chiếu thì chương trình chạy nhưng vì hàm operator+ khi đó tham chiếu đến biến rác nên chương trình bị xung đột vùng nhớ khi chạy và bị dừng khi đang chạy.
DT& DT::operator+(DT u) {
DT temp;
....
return temp;
}
Mọi người cho em hỏi tại sao để tham chiếu nó chạy được còn không thì chương trình báo lỗi luôn.
Có cách nào để hàm trả về tham chiếu 1 biến cục bộ không như ở trên em muốn hàm trả về tham chiếu đến biến temp.
Chịu khó thôi. Tới C++11 mới có move assignment, move constructor
thế bây giờ em muốn tính giá trị của u1+u2 thì phải làm sao.
Ai chỉ giúp em với khó hiểu ghê.
Đành phải trả value về chứ sao giờ trả về ref thì bị sút ra vì dangling ref rồi. Nếu ko muốn alloc thêm thì cài op+= rồi dùng friend function 3 tham số, vẫn giữ được OOP.
Em đã thử làm lại bằng cách cấp phát bộ nhớ:
và chương trình đã chạy nhưng em có một vài chỗ vẫn không hiểu mong anh chỉ giúp.
1: Tại sao trả về tham chiếu nó lại cho gán u=u1+u2 trong khi trả về tham trị thì lại không.
2.Tại sao khi em cấp phát bộ nhớ thì lại có thể dùng hàm trả về tham chiếu còn không cấp phát thì lại bị dangling ref.
Vì đơn giản là cấp phát qua raw pointer thì hàm sẽ không tự hủy.
When is the destructor of the temporary called
ý anh là khi cấp phát trên heap thì return temp sẽ bị leak mem phải return *temp.
Anh trả lời giúp em câu 1 nữa.
Mình xem lại rồi, nên trả về temp luôn, vì compiler có thể dùng tham số ẩn để giữ temp (gọi là RVO),
return *temp;
sẽ không hay bằng vì nó bịnew
ra.Câu 1 thì nhiều khả năng bạn cài đặt sai op= vì mình viết như vậy có sao đâu.
Hàm trả về tham chiếu mà anh sao trả về con trỏ được.
Đương nhiên bạn phải sửa kiểu trả về ở prototype chứ
p/s: op+ leak mem. Nên viết copy constructor luôn cho đủ bộ ba.
Phân tích: Vấn đề là khi viết “khơi khơi” thì hàm có trách nhiệm gọi destructor, trỏ vào bằng con trỏ hay ref rồi trả về đều là sai vì sau đó là mất luôn. Còn bạn
new
ra thì hàm không hủy nên trỏ hay ref gì cũng được (đừng trả về ref, leak mem trừ phi có moving assignment/constructor).Sao em thử gán: u=u1+u2 mà vẫn không được vậy. Vẫn phải để DT& hoặc DT* thì mới gán được còn nếu trả về tham trị thì nó không cho gán.
Rõ ràng là đơn giản chỉ trả về giá trị của temp rồi gán temp cho u mà sao phải trả về DT& hoặc DT* vậy anh.
Kiểu như em viết hàm tính tổng của 2 số nguyên đâu cần phải trả về tham chiếu gì đâu mà vẫn gán được u=u1+u2;
Cho em hỏi ngu chút leak mem là sao vậy anh. Google nó toàn ra memory leak.
Bạn phải cài copy constructor rồi. Sau đó ở op= sửa lại thành tham trị là giải quyết được lỗi này. (gọi là copy-and-swap idiom)
Bởi vì tham chiếu không được gán bằng rvalue, mà hàm luôn trả về rvalue.
Em viết hàm copy constructor rồi anh nó chạy được không cần phải trả về DT& hay DT* gì cả nhưng sao lại còn phải sửa cả operator= là sao anh.