2012-09-02 50 views
6

thể trùng lặp:
Private virtual method in C++C++: chức năng ảo cá nhân so với khái niệm hàm ảo thuần túy

Nếu tôi hiểu đúng từ bài này (Private virtual method in C++), làm cho một hàm ảo trong một lớp cơ sở làm cho các lớp dẫn xuất có thể ghi đè lên nó. Nhưng dường như mọi thứ dừng lại ở đó.

Nhưng nếu hàm lớp ảo cơ sở là thuần túy, sẽ buộc các lớp dẫn xuất thực hiện hàm. Do đó, một chức năng ảo thuần túy (public) chỉ đơn thuần là một giao diện. Tôi có thể thấy một lợi ích ở đây.

Mặt khác, bằng cách đặt một lớp cơ sở hàm ảo riêng tư, chỉ cung cấp cho lớp dẫn xuất khả năng ghi đè hàm, nhưng tôi thấy không có lợi ích gì về điều này. Nó giống như là chức năng ảo riêng đó không có ở đó. Lớp dẫn xuất rõ ràng là không biết về sự tồn tại của hàm ảo đó trong lớp cơ sở vì nó là riêng, vì vậy có lợi ích nào khi khai báo một lớp riêng ảo cơ sở, về mặt thừa kế hay đa hình?

Ngoài ra, có bất kỳ tình huống nào mà một lớp cơ sở khai báo một hàm 'thuần ảo' và 'riêng tư' không?

Cảm ơn bạn.

Trả lời

12

Một lợi ích là trong việc thực hiện template method pattern:

class Base { 

public : 
    void doSomething() { 
    doSomething1(); 
    doSomething2(); 
    doSomething3(); 
    } 
private: 
    virtual void doSomething1()=0; 
    virtual void doSomething2()=0; 
    virtual void doSomething3()=0; 
}; 


class Derived : public Base { 
    private: 
    virtual void doSomething1() { ... } 
    virtual void doSomething2() { .... } 
    virtual void doSomething3() { .... } 
} 

Điều này cho phép các lớp thừa kế để thực hiện từng đoạn một logic nhất định, trong khi các lớp cơ sở xác định làm thế nào để đặt những mảnh với nhau. Và vì các phần không có ý nghĩa của chính chúng, chúng được khai báo private và do đó bị ẩn khỏi mã máy khách.

0

Nếu phương pháp là ảo, nó có thể bị ghi đè bởi các lớp dẫn xuất, ngay cả khi nó là riêng tư. Dù sao, nó phải được tuyên bố với bảo vệ.

+2

Tại sao tuyên bố nó được bảo vệ nếu bạn biết rằng bạn sẽ không bao giờ cần truy cập vào phương thức cơ sở từ các lớp dẫn xuất? Bạn có thể ghi đè điều gì đó mà không cần phải gọi nó. –

+0

http://www.parashift.com/c++-faq-lite/private-virtuals.html – Samson

+0

Không có lý do gì * nên * được khai báo là 'được bảo vệ'. Nếu bạn cần 'bảo vệ', hãy sử dụng nó. Nếu không, hãy sử dụng 'private'. – juanchopanza

3

Đó là cho các tình huống mà cơ sở muốn con mình thực hiện chức năng mà chính cơ sở cần sử dụng. Hãy tưởng tượng một ví dụ ngớ ngẩn - xe hơi.

class Car { 
public: 
    int getTorque(); 
    int getPower(); 

private: 
    virtual const Engine& gimmeEngine() = 0; 
}; 

class Ferrari : public Car { 
private: 
    FerrariEngine myCoolEngine; 
    const Engine& gimmeEngine() { return myCoolEngine; } 
}; 

Bây giờ xe không cần phải biết gì về động cơ của Ferrari, duy nhất mà nó thực hiện một số giao diện Engine rằng guaranties rằng Car có thể nhận được thông tin về quyền lực và mô-men xoắn của nó.

Trong ví dụ ngớ ngẩn này, mọi thứ có thể được đơn giản hóa bằng cách tạo getTorquegetPower ảo thuần túy, nhưng tôi hy vọng nó minh họa ý tưởng. Base cần phải sử dụng một số logic cụ thể nó biết mọi trẻ em phải có, do đó, nó truy vấn nó thông qua một thành viên ảo tư nhân thuần túy.

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