2010-05-07 43 views
8
class Base 
{ 
public: 
    virtual void foo() const 
    { 
     std::cout << "Base"; 
    } 
}; 

class Derived : public Base 
{ 
public: 
    virtual void foo() const 
    { 
     std::cout << "Derived"; 
    } 
}; 

Derived d; // call Base::foo on this object 

Con trỏ truyền và chức năng cố định nhưng tôi không thể làm được. Có thể đánh bại cơ chế ảo (chỉ tự hỏi nếu nó có thể)?Gọi phương thức ảo từ lớp cơ sở trên đối tượng có nguồn gốc

+0

có thể trùng lặp của [Cách gọi phương thức lớp cơ sở thông qua con trỏ lớp cơ sở trỏ đến lớp dẫn xuất] (http://stackoverflow.com/questions/1136249/how-to-call-base-class-method-through-base -class-pointer-point-to-derived-cla) – outis

Trả lời

24

Để gọi một cách rõ ràng chức năng foo() quy định tại Base, sử dụng:

d.Base::foo(); 
+0

+1 cho bạn quá Daniel - lạ như thế nào bạn đang trả lời đã không hiển thị lúc đầu cho tôi. – ChrisBD

+1

@ ChrisBD: Sau khi đăng nó, tôi đột nhiên nhận ra rằng tôi không thể nhớ bao giờ có sử dụng cấu trúc này trực tiếp (chỉ bên trong định nghĩa của hàm trong lớp dẫn xuất). Do đó, tôi quyết định xóa nó một lúc, cho đến khi tôi chắc chắn nó đã hoạt động. –

6
d.Base::foo(); 

Lưu ý rằng sẽ gọi Derived::foo bất kể foo là ảo hay không.

+0

+1 @Marcelo - bạn quá nhanh với tôi :) – ChrisBD

+1

Er ... Trên thực tế, một tên đủ điều kiện sẽ bị đánh bại * dispath ảo * cụ thể. Bạn dường như giả định rằng lệnh 'd.foo()' không phải là ảo. Ngôn ngữ không nói như thế. Lệnh 'd.foo()' là * virtual * từ quan điểm ngôn ngữ, tức là nó được giải quyết theo kiểu động của 'd'. Nếu trình biên dịch của bạn gửi nó tĩnh, nó không là gì khác hơn là một tối ưu hóa được thực hiện bởi trình biên dịch của bạn (vì kiểu động được biết ở thời gian biên dịch). Từ quan điểm ngôn ngữ, cách duy nhất để đánh bại công văn ảo là sử dụng tên đầy đủ. – AnT

+0

Vâng nó đánh bại cả hai. Nhưng 'b-> Base :: foo' * chỉ * đánh bại công văn ảo. –

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