2011-06-20 4 views
9

Sự khác biệt giữa quá tải nhà điều hành = trong một lớp học và các nhà xây dựng bản sao là gì?Sự khác nhau giữa toán tử quá tải = và nạp chồng quá trình tạo bản sao là gì?

Trong đó mỗi ngữ cảnh được gọi là ngữ cảnh?

Ý tôi là, nếu tôi có như sau:

Person *p1 = new Person("Oscar", "Mederos"); 
Person *p2 = p1; 

Cái nào được sử dụng? Và sau đó khi người khác được sử dụng?

Edit:
Chỉ cần làm rõ một chút:

tôi đã biết rằng nếu chúng ta dứt khoát gọi các bản sao constructor Person p1(p2), các nhà xây dựng bản sao sẽ được sử dụng. Điều tôi muốn biết là khi mỗi cái được sử dụng, nhưng thay vào đó, sử dụng toán tử =, như @Martin đã chỉ ra.

Trả lời

12

Trong trường hợp của bạn, không được sử dụng khi bạn đang sao chép con trỏ.

Person p1("Oscar", "Mdderos"); 
Person extra; 

Các constructor sao chép

Person P2(p1);  // A copy is made using the copy constructor 
Person P3 = p2; // Another form of copy construction. 
        // P3 is being-initialized and it uses copy construction here 
        // NOT the assignment operator 

Một bài tập lớn:

extra = P2;   // An already existing object (extra) 
        // is assigned to. 

Điều đáng nói rằng toán tử gán có thể được viết về các nhà xây dựng bản sao bằng cách sử dụng Copy and Swap idium:

class Person 
{ 
    Person(std::string const& f, std::string const& s); 
    Person(Person const& copy); 

    // Note: Do not use reference here. 
    //  Thus getting you an implicit copy (using the copy constructor) 
    //  and thus you just need to the swap 
    Person& operator=(Person copy) 
    { 
     copy.swap(*this); 
     return *this; 
    } 

    void swap(Person& other) throws() 
    { 
      // Swap members of other and *this; 
    } 
}; 
+0

+1: Nhưng để tránh nhầm lẫn, câu trả lời của bạn có lẽ cũng nên bao gồm 'Person p3 = p1' làm ví dụ khác về hàm tạo bản sao. –

+0

Vì vậy, các nhà xây dựng bản sao chỉ được sử dụng một cách rõ ràng? Không bao giờ sử dụng '='? –

+0

@OliCharlesworth Chính xác. Tôi đang nghi ngờ về nó ... –

5

Trình tạo bản sao là một constructor , nó tạo ra một đối tượng. Đặc biệt, các nhà xây dựng bản sao tạo ra một đối tượng mà là ngữ nghĩa giống nhau, đối tượng, trong đó nó làm cho một "bản sao" đã tồn tại:

Person newperson(oldperson); // newperson is a "copy" of oldperson 

Việc chuyển nhượng hành không phải là một nhà xây dựng ở tất cả, nhưng một thành viên thông thường funcion chỉ có thể được gọi trên một đối tượng hiện có. Mục đích của nó là gán cho đối tượng của bạn ngữ nghĩa của một đối tượng khác, để sau khi phân công hai ngữ nghĩa giống nhau về mặt ngữ nghĩa. Bạn thường không "quá tải" toán tử gán, bạn chỉ định nghĩa nó.

Person p;   // construct new person 
/* dum-dee-doo */ 
p = otherperson; // assign to p the meaning of otherperson, overwriting everything it was before 
        // invokes p.operator=(otherperson) 

Lưu ý rằng nếu nó làm cho tinh thần để so sánh với các đối tượng (với ==), sau đó cả hai xây dựng sao chép và phân công nên cư xử để chúng tôi có sự bình đẳng sau:

Person p1(p2); 
assert(p1 == p2); 

p1 = p3; 
assert(p1 == p3); 

Bạn không bắt buộc để đảm bảo điều này, nhưng người dùng trong lớp của bạn thường sẽ giả định hành vi này. Trong thực tế, trình biên dịch giả định rằng Person p1; Person p2(p1); đòi hỏi phải có p1 == p2;.

Cuối cùng, như một thức sang một bên và như đã nói ở nơi khác, lưu ý rằng Person p = p2;theo nghĩa đen có nghĩa làPerson p(p2) (xây dựng bản sao), và không bao giờ Person p; p = p2;.Đó là đường cú pháp để cho phép bạn viết mã trông tự nhiên mà không ảnh hưởng đến hiệu quả (hoặc thậm chí chính xác, vì lớp của bạn có thể thậm chí không được cấu hình mặc định).

+0

Cảm ơn câu trả lời của bạn. Tôi có nghĩa là sự khác biệt khi làm '='. Tất nhiên là khi thực hiện 'Person x (y)' bạn đang gọi hàm tạo bản sao. Bạn biết ý tôi là gì không? –

+0

@Oscar: Xin lỗi, tôi không hiểu ý bạn là gì bởi "sự khác biệt khi làm' = '". Bạn có thể vui lòng nói lại hoặc làm rõ câu hỏi hoặc điểm không chắc chắn của bạn? –

0

Trình tạo bản sao xây dựng một đối tượng mới bằng cách sử dụng nội dung của đối tượng đối số. An toán tử gán quá tải gán nội dung của đối tượng hiện có cho đối tượng hiện có của cùng một lớp.