2013-07-24 44 views
5

Tôi có một sự nhầm lẫn về việc thừa kế thuộc tính ảo của một phương thức. Giả sử chúng ta có 4 lớp: lớp A, lớp B, lớp C và lớp D. Các lớp được kế thừa theo cách này: A -> B -> C -> D, trong đó A là lớp cơ sở. Vào lúc này, tôi chắc chắn về điều này: Bắt đầu khai báo phương thức lớp với virtual trong lớp cơ sở (class A), làm cho phương thức ảo cho tất cả các lớp bắt nguồn từ lớp cơ sở, bao gồm cả các lớp dẫn xuất của lớp các lớp dẫn xuất. (Các phương thức lớp B và C được xác định là ảo).Thừa kế chức năng ảo

Sự nhầm lẫn ở đây. Điều gì xảy ra nếu, trong lớp cơ sở A, sẽ không có bất kỳ thành viên ảo nào. Thay vào đó, hãy nói rằng lớp B tuyên bố một phương thức là ảo. Tôi cho rằng, sự thay đổi này sẽ làm cho hàm ảo cho tất cả các lớp dẫn xuất thuộc về chuỗi kế thừa (các lớp C và D). Vì vậy, hợp lý, B cho C và D, là một loại "lớp cơ sở" của họ, phải không? Hoặc là tôi sai?

Trả lời

13

Bạn chính xác.

Tôi nghĩ rằng trong trường hợp này là giải pháp tốt nhất là để thử:

#include <iostream> 

using namespace std; 

class A { 
    public: 
     void print(){ cout << "print A" << endl; }; 
}; 

class B: public A { 
    public: 
     virtual void print(){ cout << "print B" << endl; }; 
}; 

class C: public B { 
    public: 
     void print(){ cout << "print C" << endl; }; 
}; 

int main() 
{ 
    A *a = new C(); 
    B *b = new C(); 

    a->print(); // will print 'print A' 
    b->print(); // will print 'print C' 

    return 1; 
} 
5

Bạn hoàn toàn chính xác. Trẻ thừa kế những gì tổ tiên của nó có. Các lớp cơ sở không thể kế thừa những gì con có (chẳng hạn như một hàm hoặc biến mới). Các hàm ảo là các hàm đơn giản có thể được ghi đè bởi lớp con nếu lớp con đó thay đổi việc thực hiện hàm ảo sao cho hàm ảo cơ sở không được gọi.

A là lớp cơ sở cho B, C, D. B là lớp cơ sở cho C, D. và C là lớp cơ sở cho D.

+0

gợi ý nhanh: nếu lớp cơ sở có một phương thức ảo, nên tôi làm nổi bật phần còn lại của phương pháp ảo thuộc về các lớp được thừa với từ khóa ảo? Chỉ để thể hiện rõ hơn. –

+0

Không phải là không cần thiết. Làm điều đó một lần trong lớp cơ sở cung cấp cho tất cả các lớp con khả năng thay đổi việc thực hiện hàm (tất cả được thừa kế). – theta

+0

@RobertEagle Thêm 'virtual' hoặc' override' vào các lớp dẫn xuất là không cần thiết *, nhưng tôi sẽ nói _yes_, đó là một cách hay để đặt lời nhắc trực quan về ngữ nghĩa của hàm bất cứ khi nào có thể. * trừ khi sử dụng một trình biên dịch như 'g ++' cung cấp cảnh báo nếu các vòng loại này bị thiếu, và bạn nói để xử lý cảnh báo là lỗi. –

0

Tất nhiên bạn có thể làm điều đó. Phương pháp ảo là tùy chọn để ghi đè vì vậy không quan trọng là bạn khai báo nó trong lớp A hoặc B. Nếu bạn không muốn sử dụng phương thức đó trong lớp A thì chỉ cần khai báo trong lớp B.

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