2010-04-19 48 views
10

Tôi có một câu hỏi, đây là hai lớp dưới đây:Hành vi chức năng ảo trong C++

class Base{ 
     public: 
      virtual void toString();  // generic implementation 
    } 

    class Derive : public Base{ 
     public: 
      (virtual) void toString(); // specific implementation 
    } 

Câu hỏi đặt ra là:

  • Nếu tôi muốn lớp con của lớp lấy biểu diễn các polymophism sử dụng con trỏ của loại Cơ sở, là từ khóa ảo trong khung cần thiết?

  • Nếu câu trả lời là không, sự khác biệt giữa chức năng thành viên toString của lớp Rút ra có và không có ảo là gì?

+1

Nó là tùy chọn nhưng một số xem xét nó là một vấn đề của phong cách tốt để được rõ ràng về trọng các chức năng thành viên. – pmr

Trả lời

13

C++ 03 §10.3/2:

Nếu một ảo chức năng thành viên vf được tuyên bố trong một lớp học cơ sở và trong một lớp học nguồn gốc, xuất phát trực tiếp hoặc gián tiếp từ Base, một thành viên chức năng vf có cùng tên và cùng danh sách tham số dưới dạng Base :: vf là được khai báo, sau đó Có nguồn gốc :: vf cũng là ảo (có hoặc không là ) và ghi đè Cơ sở :: vf.

+2

+1 để trích dẫn tham chiếu thực tế –

10

Từ khóa đó hoàn toàn tùy chọn và không có sự khác biệt nào cả.

+11

Nó không tạo sự khác biệt cho trình biên dịch. Để người đọc nó có thể trong thực tế cải thiện khả năng đọc. Tôi luôn tuyên bố rõ ràng là ảo ở mọi cấp độ thừa kế. –

7

Thuộc tính virtual được kế thừa từ lớp cơ sở và được giả định là có mặt ngay cả khi bạn không nhập.

1

Trình biên dịch đã biết từ khóa 'ảo' trong lớp cơ sở mà toString là một phương thức ảo. Không cần phải lặp lại nó.

+4

Người ta có thể thêm rằng nó có thể tạo sự khác biệt cho người đọc của con người. – sbi

1

Chức năng khi ảo luôn là ảo.

Vì vậy, trong mọi trường hợp nếu từ khóa ảo không được sử dụng trong các lớp tiếp theo, nó không ngăn chức năng/phương pháp bị 'ảo' tức là bị ghi đè. Vì vậy, phương châm sau đây có thể giúp từ một điểm-of-view phát triển đội ngũ: -

  • Nếu hàm/phương pháp được coi được ghi đè, luôn luôn sử dụng từ khóa 'ảo'. Điều này đặc biệt là đúng khi được sử dụng trong các lớp giao diện/cơ sở .
  • Nếu lớp dẫn xuất được giả định là được phân loại tiếp theo, hãy giải thích nêu từ khóa 'ảo' cho mọi chức năng/phương pháp có thể bị ghi đè .
  • Nếu hàm/phương pháp trong các nguồn gốc lớp không được coi là tiểu phân loại một lần nữa, sau đó từ khóa 'ảo' là để lấy ý kiến ​​ chỉ ra rằng chức năng/phương pháp được ghi đè nhưng không có các lớp học khác sẽ ghi đè lại nó . Điều này ofcourse không ngăn chặn một người nào đó từ trọng trong các lớp học có nguồn gốc trừ khi lớp được thực hiện cuối cùng (không thể phái sinh), nhưng nó chỉ ra rằng phương pháp này không được coi là ghi đè. Ví dụ: /*virtual*/ void someFunc();
+0

Đối với trường hợp "bị ghi đè luôn", người ta cũng có thể muốn thêm bộ định danh thuần túy. – Myke

+0

Tôi nghĩ rằng có nghĩa là một dấu phẩy giữa "ghi đè" và "luôn luôn". tức là "luôn sử dụng từ khóa' virtual' "và không phải" luôn ghi đè ". –

+0

@Ben: bạn nói đúng, Thnx. – Abhay

0

Nó không quan trọng cho biên dịch hay không, bạn cung cấp ảo từ khóa trên các phiên bản bắt nguồn của hàm.

Tuy nhiên, tốt hơn hết nên cung cấp nó, để bất kỳ ai xem mã của bạn đều có thể cho biết đó là chức năng ảo.

0

Đó là vấn đề về phong cách tốt và người lập trình người dùng biết điều gì đang xảy ra. Trong C++ 0x bạn có thể sử dụng [[ghi đè]] để làm cho nó rõ ràng và rõ ràng hơn. Bạn có thể sử dụng [[base_check]] để bắt buộc sử dụng [[override]].

Nếu bạn không muốn hoặc không thể làm điều đó, chỉ cần sử dụng từ khóa ảo.

Nếu bạn lấy được mà không có toString ảo, và bạn đưa một thể hiện của Derive về Base, gọi toString() thực sự sẽ gọi Base's toString(), theo như nó biết đó là một thể hiện của Base.

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