2014-12-13 13 views
5

Tôi đã cố gắng tìm rất nhiều rằng điều gì sẽ xảy ra nếu chỉ có một lớp được tạo ảo trong nhiều thừa kế? Hành vi của cuộc gọi hàm tạo không rõ ràng đối với tôi trong trường hợp này. Hãy nói ví dụ số-Trình tự các cuộc gọi hàm tạo trong nhiều thừa kế

#include<iostream> 
using namespace std; 
class grand{ 
public: 
    grand(){cout<<"grandfather"<<endl;} 
}; 
class parent1:virtual public grand{ //virtual used only here 
public: 
    parent1(){cout<<"parent1 "<<endl;} 
}; 
class parent2: public grand{ 
public: 
    parent2(){cout<<"parent2"<<endl;} 
}; 
class child:public parent1,public parent2{ 
public: 
    child(){cout<<"child"<<endl;} 
}; 
int main() { 
    child s; 
    return 0; 
} 

Kết quả của đoạn mã này được đưa ra khi

grandfather 
parent1 
grandfather 
parent2 
child 

nhưng trong đoạn code trên nếu chúng ta thay đổi này

class parent1:virtual public grand{ 
public: 
    parent1(){cout<<"parent1 "<<endl;} 
}; 
class parent2: public grand{ 
public: 
    parent2(){cout<<"parent2"<<endl;} 
}; 

này

class parent1:public grand{ //virtual removed from here 
public: 
    parent1(){cout<<"parent1 "<<endl;} 
}; 
class parent2:virtual public grand{ //virtual is added here 
public: 
    parent2(){cout<<"parent2"<<endl;} 
}; 

đầu ra được hiển thị là

grandfather 
grandfather //why parent1 constructor is not called here? 
parent1 
parent2 
child 

Quan tâm của tôi là lý do tại sao hàm tạo parent1 không được gọi sau ông nội?

+0

bản sao có thể có của [Thừa kế ảo, một lớp đủ?] (Http://stackoverflow.com/questions/13752482/virtual-inheritance-one-class-enough) – Mikhail

+1

Không có điều này là về * thứ tự các cuộc gọi * không phải về * tự chia sẻ *. –

Trả lời

5

Tiêu chuẩn nói [C++ 11 phần 12.6.2/10] rằng: Để

Trong một constructor không ủy thác, tiền thu được khởi tạo trong sau:

- Thứ nhất, và chỉ dành cho hàm tạo của lớp dẫn xuất nhất, các lớp cơ sở ảo được khởi tạo theo thứ tự chúng xuất hiện trên một giao lộ trái-phải-trái-phải theo chiều dọc đầu tiên của biểu đồ tuần hoàn theo hướng các lớp cơ sở, trong đó “từ trái sang phải ”Là thứ tự xuất hiện của các lớp cơ sở i n lớp cơ sở-specifier-danh sách có nguồn gốc.

- Sau đó, các lớp cơ sở trực tiếp được khởi tạo theo thứ tự khai báo là chúng xuất hiện trong danh sách-specifier-list (bất kể thứ tự của mem-initializers).

- Sau đó, thành viên dữ liệu không tĩnh được khởi tạo theo thứ tự là được khai báo trong định nghĩa lớp (một lần nữa bất kể thứ tự của bộ khởi tạo mem).

- Cuối cùng, tuyên bố hợp chất của phần thân hàm tạo được thực hiện.

Vì vậy, các lớp cơ sở ảo của bạn luôn được xây dựng trước ... Điều này thực sự quan trọng trong trường hợp chia sẻ lớp cơ sở ảo.

+0

Thanks.As bạn đã nói các lớp ảo được xây dựng trước nhưng sau khi đọc nó vẫn không rõ ràng tại sao "parent1" không được gọi ngay sau "ông nội". Bạn có thể thêm một số ví dụ vào câu trả lời của mình không? – Ankur

+1

Ok, Bạn phải xây dựng lớp cơ sở ảo cho 'parent2' trước (quy tắc 1). Sau đó, bạn phải xây dựng 'parent1' và sau đó' parent2' theo thứ tự đó khi chúng được khai báo như vậy (quy tắc 2). Nhưng để xây dựng 'parent1' bạn cần phải xây dựng một thể hiện' grand' đầu tiên nhưng không phải là một cá thể ảo (quy tắc 2). Vì vậy, điều này sẽ cung cấp cho bạn thứ tự sau: 'grand' (virtual),' grand' (cho parent1), 'parent1',' parent2' (sử dụng virtual grand được tạo ở đầu) và sau đó là 'child'. –

+0

Cảm ơn đã nhận điều này ngay bây giờ :) – Ankur

Các vấn đề liên quan