2009-06-08 39 views
5

Tôi có một lớp trừu tượng với một vài chức năng ảo tinh khiết, và một trong những lớp học tôi rút ra từ nó không sử dụng một trong những chức năng ảo tinh khiết:Có cách nào để "xóa" một chức năng ảo thuần túy không?

class derivative: public base 
{ 
public: 
    int somevariable; 
    void somefunction(); 
}; 

anyways, khi tôi cố gắng để biên dịch nó, tôi nhận được một lỗi (rõ ràng, một lớp vẫn được coi là trừu tượng nếu lấy được từ một lớp trừu tượng và không ghi đè tất cả các hàm ảo thuần túy). Dù sao, có vẻ như vô nghĩa để xác định một hàm

int purevirtfunc(){return 0;} 

chỉ vì nó cần được xác định thông qua kỹ thuật. Có cách nào để lấy được một lớp từ một lớp trừu tượng và không sử dụng một trong các hàm ảo thuần túy của lớp trừu tượng không?

+6

Nếu có cách nào, bạn mong đợi điều gì sẽ xảy ra nếu mã được gọi là một trong những phương pháp chưa được thực hiện đó? – Aardvark

Trả lời

40

Nếu lớp dẫn xuất của bạn không "sử dụng" lớp cơ sở thuần hàm ảo, thì lớp dẫn xuất không được bắt nguồn từ cơ sở hoặc PVF không nên ở đó. Trong cả hai trường hợp, thiết kế của bạn có lỗi và cần được suy nghĩ lại.

Và không, không có cách nào để xóa PVF.

1

Khi bạn kế thừa từ một lớp có chức năng ảo thuần túy, bạn PHẢI thực hiện các chức năng đó. Nếu không, thì lớp dẫn xuất của bạn cũng trừu tượng và bạn không thể tạo một đối tượng của lớp dẫn xuất.

+0

Bạn cũng có thể tạo một bản thực hiện rỗng mà bạn thừa hưởng từ đó sẽ làm cho bạn khó khăn nếu bạn thường xuyên thừa kế từ giao diện này. –

9

Mục đích của việc phát sinh từ các lớp trừu tượng là mã bên ngoài có thể sử dụng lớp trừu tượng và mong đợi rằng tất cả các hàm đã được triển khai đúng cách. Có thể unimplement một phương pháp sẽ đánh bại mục đích này, làm cho mã uncompilable. Bạn được tự do để ném một ngoại lệ, nếu bạn chọn như vậy, tuy nhiên.

1

Không. Cung cấp triển khai mặc định trong lớp cơ sở hoặc triển khai đơn giản trong lớp dẫn xuất, như bạn đã đề xuất.

14

Lớp ảo thuần túy là giao diện, một giao diện mà mã của bạn sẽ được đáp ứng. Điều gì sẽ xảy ra nếu bạn thực hiện giao diện đó và không thực hiện một trong các phương pháp? Mã sẽ gọi giao diện của bạn biết rằng bạn đã không triển khai phương thức như thế nào?

lựa chọn của bạn là:

  1. Thực hiện phương pháp này như bạn mô tả (làm cho nó tin sẽ chỉ ra rằng nó không nên được sử dụng).
  2. Thay đổi thứ bậc lớp học của bạn để xem xét thay đổi thiết kế.
5

Đó không phải là kỹ thuật. Nếu lớp dẫn xuất của bạn không biểu hiện tất cả các hành vi của cha mẹ, nó không nên được bắt nguồn từ cha mẹ. Đây là một mùi thiết kế chính, và bạn có thể cần một số refactoring thiết kế.

0

Cho phép điều này sẽ không có ý nghĩa gì. Điều gì sẽ xảy ra nếu bạn gọi hàm này mà không cần triển khai? Một lỗi thời gian chạy (có thể là ngớ ngẩn)? Bạn có thể tranh luận rằng nó có thể là một lỗi thời gian biên dịch trong một số trường hợp, nhưng điều này là không thể nếu loại chính xác không được biết (e.i. bạn chuyển một con trỏ tới một thể hiện của lớp dẫn xuất đến một hàm).

1

Đã có câu trả lời hay, nhưng nếu bạn muốn biết thêm thông tin từ phía thiết kế OO lý thuyết, hãy xem Liskov substitution principle.

0

Như nhiều người đã tuyên bố, có vẻ như phương pháp cơ sở không phải là ảo thuần túy hoặc bạn nên suy nghĩ lại liệu lớp gốc của bạn có thực sự là cơ sở ISA hay không.

Tuy nhiên, có thể cung cấp triển khai cho phương pháp ảo thuần túy trong lớp cơ sở. Điều này có thể hoạt động như một sự thực thi mặc định cho các lớp dẫn xuất, nhưng bạn vẫn yêu cầu lớp dẫn xuất để chọn sự triển khai thực hiện của lớp cơ sở.

Tôi không biết liệu điều đó có giúp ích cho bạn hay không.

-1

Không thể bạn chỉ cần làm

class Foo { 
public: 
    virtual void foo() = 0; 
}; 

class Bar { 
public: 
    virtual void foo() = delete; 
}; 
0

Không, không có. Quy ước trong ngôn ngữ bị ràng buộc muộn khi tình huống này xảy ra (vì nó có thể hợp pháp, nhưng hãy xem xét thiết kế của bạn để xem liệu phương pháp này có thể được di chuyển ở nơi khác, có lẽ đến lớp trừu tượng của nó) hay không. phương pháp biết rằng một số triển khai có thể làm tăng ngoại lệ đó.

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