2015-04-17 29 views
5

Có bao giờ có ý nghĩa khi ghi đè phương thức ảo thuần túy bằng một phương thức ảo thuần túy khác không? Có bất kỳ sự khác biệt chức năng hoặc có lẽ lý do kiểu mã để thích một trong các tùy chọn sau khác?C++ ghi đè phương pháp ảo thuần túy với phương pháp ảo thuần túy

class Interface { 
public: 
    virtual int method() = 0; 
}; 

class Abstract : public Interface { 
public: 
    int method() override = 0; 
}; 

class Implementation : public Abstract { 
public: 
    int method() override { return 42; } 
}; 

Versus:

class Interface { 
public: 
    virtual int method() = 0; 
}; 

class Abstract : public Interface {}; 

class Implementation : public Abstract { 
public: 
    int method() override { return 42; } 
}; 
+1

Nó chỉ có thể phục vụ để truyền đạt điều gì đó cho người đọc mã của bạn. * "Người thân tìm kiếm mã Tóm tắt của tôi ... lưu ý rằng lớp này thực sự có chức năng ảo." –

Trả lời

4

Cả hai mã tạo ra hiệu ứng tương tự: lớp Abstract là trừu tượng và bạn không thể khởi tạo nó.

Tuy nhiên có một sự khác biệt về ngữ nghĩa giữa hai hình thức:

  • Các hình thức đầu tiên nhắc nhở rõ ràng rằng lớp Abstract là trừu tượng (chỉ trong trường hợp tên của nó sẽ không được tự sepaking đủ ;-)). Nó không chỉ nhắc nhở nó: nó cũng đảm bảo nó bằng cách đảm bảo rằng phương thức đó là ảo thuần túy.
  • Biểu mẫu thứ hai có nghĩa là lớp học Abstract kế thừa mọi thứ chính xác từ Interface. Nó trừu tượng khi và chỉ khi lớp cơ sở của nó là.

Điều này có hậu quả đối với diễn biến trong tương lai của mã của bạn. Ví dụ, nếu một ngày nào đó bạn thay đổi suy nghĩ của bạn và muốn giao tiếp để có một thực hiện mặc định cho method():

  • Trong hình thức đầu tiên Absract vẫn trừu tượng và sẽ không kế thừa thực hiện mặc định của phương pháp.
  • Biểu mẫu thứ hai đảm bảo rằng Abstact sẽ tiếp tục kế thừa và hoạt động chính xác như Interface.

Cá nhân tôi thấy rằng biểu mẫu thứ hai trực quan hơn và đảm bảo tách mối quan tâm tốt hơn. Nhưng tôi có thể tưởng tượng rằng có thể có một số tình huống là hình thức đầu tiên thực sự có ý nghĩa.

4

Đặc điểm kỹ thuật thuần túy trên phương pháp buộc ghi đè, nhưng nó không ngăn cản bạn cung cấp phương pháp triển khai phương pháp. Sau đây là một kỹ thuật hiếm, nhưng đôi khi hữu ích.

class Interface 
{ 
    virtual void method() = 0; 
}; 

class Abstract : public Interface 
{ 
    virtual void method() = 0; 
} 
inline void Abstract::method() 
{ 
    do something interesting here; 
} 

class Concrete : public Abstract 
{ 
    virtual void method(); 
} 

inline void Concrete::method() 
{ 
    // let Abstract::method() do it's thing first 
    Abstract::method(); 
    now do something else interesting here; 
} 

Điều này đôi khi hữu ích nếu có một số lớp bắt nguồn từ Tóm tắt cần một số chức năng chung, nhưng cũng cần thêm hành vi cụ thể của lớp. [và nên buộc phải cung cấp hành vi đó.]

+1

Lưu ý 'inline' chỉ là để làm cho mã có ý nghĩa nếu tất cả xuất hiện trong một tiêu đề. Trong thực tế bạn có lẽ nên tránh các phương pháp ảo nội tuyến! –

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