2009-10-01 4 views
5
class Base 
{ 
     public: 
     int i; 

     Base() 
     { 
      cout<<"Base Constructor"<<endl; 
     } 

     Base (Base& b) 
     { 
      cout<<"Base Copy Constructor"<<endl; 
      i = b.i; 
     } 


     ~Base() 
     { 
      cout<<"Base Destructor"<<endl; 
     } 

     void val() 
     { 
      cout<<"i: "<< i<<endl; 
     }  
}; 

class Derived: public Base 
{ 
     public: 
     int i; 

     Derived() 
     { 
      Base::i = 5;  
      cout<<"Derived Constructor"<<endl; 
     } 

     /*Derived (Derived& d) 
     { 
      cout<<"Derived copy Constructor"<<endl; 
      i = d.i; 
     }*/ 

     ~Derived() 
     { 
      cout<<"Derived Destructor"<<endl; 
     }  

     void val() 
     { 
      cout<<"i: "<< i<<endl; 
      Base::val(); 
     } 
}; 

Nếu tôi làm Có nguồn gốc d1; Có nguồn gốc d2 = d1; Các nhà xây dựng bản sao của cơ sở được gọi là và xây dựng bản sao mặc định của nguồn gốc được gọi là.Trình tạo bản sao cơ sở không được gọi là

Nhưng nếu tôi xóa nhận xét khỏi hàm tạo bản sao có nguồn gốc thì hàm tạo bản sao cơ sở sẽ không được gọi. Có lý do cụ thể nào cho việc này không? Cảm ơn trước.

+3

IMVHO http://www.parashift.com/c++-faq-lite/ctors.html là một tài nguyên tuyệt vời để hiểu các nhà xây dựng C++. (Và trên thực tế, C++ FAQ Lite nói chung là một nguồn thông tin đáng kinh ngạc cho người mới bắt đầu nâng cao.) – notJim

+0

Tôi nghĩ rằng bạn cơ bản destructor nên được ảo. –

Trả lời

13

Nếu bạn muốn đọc quy tắc thực tế bạn nên tham khảo C++ chuẩn 12,8/8:

Bản sao ngầm định nghĩa constructor cho lớp X thực hiện một bản sao memberwise của subobjects của nó. Thứ tự sao chép giống như thứ tự khởi tạo các căn cứ và các thành viên trong một cấu trúc do người dùng định nghĩa tor (xem 12.6.2). Mỗi subobject được sao chép theo cách thức phù hợp với loại của nó:

  • nếu subobject là loại hạng nhất, các nhà xây dựng bản sao cho lớp được sử dụng;
  • nếu subobject là một mảng, mỗi phần tử được sao chép, theo cách phù hợp với loại phần tử;
  • nếu subobject thuộc loại vô hướng, toán tử gán được gán sẵn được sử dụng.

Khi bạn định nghĩa constructor sao chép một cách rõ ràng bạn nên gọi bản sao c-tor của lớp cơ sở một cách rõ ràng.

16

Tôi nghĩ rằng bạn phải gọi một cách rõ ràng các nhà xây dựng bản sao cơ sở:

Derived (Derived& d) : Base(d) 
    { 
     cout<<"Derived copy Constructor"<<endl; 
     i = d.i; 
    } 
4

Trong Derived constructor sao chép của bạn, bạn cần phải thêm những điều sau đây:

Derived (const Derived &d) : Base(d) { } 
2

C++ không làm bất kỳ loại của "kết hợp hàm tạo". Nếu bạn không gọi một cách rõ ràng hàm tạo của lớp cơ sở, hàm mặc định được gọi (tốt, về mặt kỹ thuật, lớp con cơ sở là "giá trị được khởi tạo", nhưng đối với các lớp có các hàm tạo thì cũng giống như vậy).

1

bạn nên đọc this: giải thích cách thừa kế & thành viên đặc biệt như nhà thầu đang hoạt động.

0

Cảm ơn bạn rất nhiều. Tôi đạt được rồi. Nó có nghĩa là các cuộc gọi đến các nhà xây dựng bản sao lớp cơ sở được automagivccally thực hiện trong constructor bản sao mặc định của nguồn gốc. Trong khi đó trong trường hợp thứ hai kể từ khi tôi đang viết các nhà xây dựng bản sao của nguồn gốc tôi phải thực hiện một cuộc gọi rõ ràng để xây dựng bản sao của cơ sở. Cảm ơn một lần nữa