Gần đây tôi đã xem xét lại các nhà xây dựng bản sao, toán tử gán, sao chép swap IDOM nhìn thấy ở đây: What is the copy-and-swap idiom? và nhiều nơi khác -Sao chép constructor và thực hiện toán tử gán sự lựa chọn -
Liên kết Trên đây là một bài tuyệt vời - nhưng tôi vẫn đã có một vài câu hỏi nữa - những câu hỏi này được trả lời trong một loạt các địa điểm, trên stackoverflow và nhiều trang web khác, nhưng tôi đã không nhìn thấy rất nhiều quán -
1 - Nếu bạn có try
-catch
xung quanh khu vực nơi chúng tôi cấp phát bộ nhớ mới cho bản sao sâu trong bản sao lưu tructor? (Ive thấy cả hai cách)
2 - Liên quan đến kế thừa cho cả hàm tạo bản sao và toán tử gán, khi nào các hàm lớp cơ sở được gọi và khi nào các hàm này sẽ là ảo?
3 - Có phải std::copy
cách tốt nhất để nhân bản bộ nhớ trong trình tạo bản sao? Tôi đã thấy nó với memcpy
, và thấy những người khác nói rằng memcpy
điều tồi tệ nhất trên trái đất.
Hãy xem xét ví dụ dưới đây (Cảm ơn tất cả những phản hồi), nó nhắc nhở một số câu hỏi thêm:
4 - nên chúng tôi được kiểm tra để tự chuyển nhượng? Nếu vậy nơi
5 - Tắt câu hỏi chủ đề, nhưng tôi đã thấy hoán đổi sử dụng như: std::copy(Other.Data,Other.Data + size,Data);
nó nên là: std::copy(Other.Data,Other.Data + (size-1),Data);
nếu swap đi từ 'đầu đến cuối và các yếu tố 0 là Other.Data?
6 - Tại sao công cụ xây dựng không nhận xét (tôi phải thay đổi kích thước thành mysize) - giả sử điều này có nghĩa là bất kể thứ tự tôi viết, hàm khởi tạo sẽ luôn gọi phần tử phân bổ trước?
7 - Bất kỳ nhận xét nào khác về việc triển khai của tôi? Tôi biết mã là vô ích nhưng tôi chỉ cố gắng minh họa một điểm.
class TBar
{
public:
//Swap Function
void swap(TBar &One, TBar &Two)
{
std::swap(One.b,Two.b);
std::swap(One.a,Two.a);
}
int a;
int *b;
TBar& operator=(TBar Other)
{
swap(Other,*this);
return (*this);
}
TBar() : a(0), b(new int) {} //We Always Allocate the int
TBar(TBar const &Other) : a(Other.a), b(new int)
{
std::copy(Other.b,Other.b,b);
*b = 22; //Just to have something
}
virtual ~TBar() { delete b;}
};
class TSuperFoo : public TBar
{
public:
int* Data;
int size;
//Swap Function for copy swap
void swap (TSuperFoo &One, TSuperFoo &Two)
{
std::swap(static_cast<TBar&>(One),static_cast<TBar&>(Two));
std::swap(One.Data,Two.Data);
std::swap(One.size,Two.size);
}
//Default Constructor
TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[mysize]) {}
//TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[size]) {} *1
//Copy Constructor
TSuperFoo(TSuperFoo const &Other) : TBar(Other), size(Other.size), Data(new int[Other.size]) // I need [Other.size]! not sizw
{
std::copy(Other.Data,Other.Data + size,Data); // Should this be (size-1) if std::copy is First -> Last? *2
}
//Assignment Operator
TSuperFoo& operator=(TSuperFoo Other)
{
swap(Other,(*this));
return (*this);
}
~TSuperFoo() { delete[] Data;}
};
Cảm ơn - Đã cập nhật với ví dụ – MikeyG