2012-03-18 45 views

Trả lời

6

Khi bạn có một phương pháp học cơ sở khai báo là virtual, Để ghi đè lên nó, bạn cần phải cung cấp một chức năng với cùng một chữ ký chính xác trong lớp Derived (kiểu trả về Co-biến được phép mặc dù).

Nếu tên hàm của bạn là tương tự nhưng chữ ký trong lớp Derived thay đổi từ một trong lớp cơ sở hơn nó không được overidding nữa, Đó là function Hiding, phương pháp lớp được thừa kế ẩn phương thức của lớp cơ sở.

Chức năng Quá tải không bao giờ nằm ​​trong các lớp học, Bạn có thể quá tải các phương thức trong cùng một lớp hoặc các chức năng miễn phí nhưng không vượt quá các lớp. Khi bạn cố gắng để làm điều đó trên các lớp học, những gì bạn cuối cùng nhận được là ẩn chức năng.

Để đưa các phương thức lớp Cơ sở trong phạm vi lớp Bắt nguồn của bạn, bạn cần thêm
bổ sung using functionName, vào lớp Có nguồn gốc của bạn.

EDIT:
Đối với Q của khi sử dụng virtual trên quá tải, câu trả lời là:
Nếu bạn có ý định chức năng của lớp học của bạn được ghi đè cho polymorphism runtime bạn nên đánh dấu chúng là virtual, và không nếu bạn không có ý định như vậy.

Tốt đọc:
When to mark a function in C++ as a virtual?

+0

Để quá tải hàm thành viên lớp cơ sở trong lớp dẫn xuất, bạn chỉ cần khai báo 'using'. – Potatoswatter

+0

@Potatoswatter: Có, bạn cần phải làm điều đó ngoài việc chỉ cung cấp các phương pháp để theo nghĩa đó, nó còn hơn là chỉ cung cấp các phiên bản quá tải. –

+0

Tôi cũng đã cố gắng để xây dựng một câu trả lời, nhưng tôi không thể giải thích sự khác biệt giữa việc thực hiện một chức năng trong cơ sở ảo hay không. Bạn có thể quá tải cả hai trong cùng một cách trong một lớp học có nguồn gốc (với một chữ ký khác nhau). Và tôi nghĩ đó là một phần của câu hỏi của OP. –

3

quá tải là hoàn toàn tách biệt (trực giao với) ảo trọng.

Trong ghi đè, một hàm được thay thế bằng một chữ ký khác giống hệt nhau. Sau đó, có một số quy tắc để chọn hàm "ghi đè cao nhất", cho hàm ảo có nghĩa là hàm được định nghĩa trong lớp có nguồn gốc cao nhất. Như một trường hợp đặc biệt cho các hàm ảo, kiểu trả về của chữ ký có thể hơi khác một chút (hiệp phương sai).

Trong quá tải, chữ ký chức năng với các loại đối số khác nhau đồng thời hoạt động như các ứng viên được chọn khi bạn thực hiện cuộc gọi hàm. Có một bộ quy tắc vô cùng phức tạp để chọn đúng quy tắc, hoạt động tốt 95% thời gian và khiến bạn đau đầu khi không hợp tác.

Vì quá tải hoạt động với các chữ ký khác nhau và ghi đè tác phẩm có cùng chữ ký, chúng không thực sự ảnh hưởng lẫn nhau.

Bạn có thể nhập rõ ràng các hàm của lớp cơ sở vào một lớp dẫn xuất để mở rộng tên hàm bị quá tải. Điều này được thực hiện bởi using base_class::overload_name; bên trong lớp dẫn xuất.

0

Tôi tin rằng bạn có nghĩa là ghi đè các chức năng không phải ảo và không quá tải. Khi bạn ghi đè lên một hàm lớp cơ sở không ảo trong lớp dẫn xuất, thì cuộc gọi đến hàm được giải quyết và bị ràng buộc tại thời gian biên dịch. Điều này có nghĩa rằng cuộc gọi hàm được giải quyết dựa trên loại (hoặc con trỏ) mà trên đó hàm được gọi. Nếu bạn đang gọi hàm trên con trỏ lớp cơ sở thì phiên bản lớp cơ sở được gọi, luôn luôn. Nếu bạn sử dụng con trỏ lớp dẫn xuất thì phiên bản dẫn xuất được gọi, luôn luôn; không phân biệt đối tượng thực sự mà nó đang trỏ đến.

Trong trường hợp phiên bản lớp cơ sở được đánh dấu là ảo thì độ phân giải cuộc gọi hoặc ràng buộc được hoãn lại trong thời gian chạy dựa trên loại đối tượng mà cuộc gọi được thực hiện và không dựa trên loại con trỏ được sử dụng thuc hien cuoc goi. Điều này có nghĩa là bạn có thể sử dụng con trỏ lớp cơ sở để trỏ đến các đối tượng lớp cơ sở và lớp dẫn xuất và sau đó gọi hàm. Dựa trên loại đối tượng mà con trỏ trỏ đến, phiên bản chức năng tương ứng được gọi. Điều này có nghĩa là nếu con trỏ trỏ đến đối tượng lớp cơ sở thì phiên bản lớp cơ sở được gọi. Nếu con trỏ trỏ đến đối tượng kiểu có nguồn gốc thì hàm verion được thừa kế được gọi.

+0

Để nói một lớp Derived ** overiddes ** chức năng lớp cơ sở, từ khóa 'virtual' phải được tham gia nếu không, nó không overidding. –

+0

Không, nó vẫn còn ghi đè. Nhưng, trong trường hợp bạn không sử dụng ảo thì phiên bản lớp cơ sở được thay thế bằng phiên bản lớp dẫn xuất. Và không có cách nào để chọn phiên bản nào bạn muốn sử dụng. Bây giờ, nếu bạn muốn làm cho tất cả các phiên bản ghi đè vẫn có sẵn thì bạn nên đánh dấu chúng là ảo. – Drona

+0

Xin lỗi vì đã phá vỡ nó cho bạn nhưng nó không chính xác, nếu không có từ khóa 'virtual' thì nó không phải là overidding. –

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