2011-06-18 23 views
11

Từ khóa virtual làm gì khi ghi đè phương pháp? Tôi không sử dụng nó và mọi thứ hoạt động tốt.Từ khóa ảo có ý nghĩa gì khi ghi đè phương thức?

Mọi trình biên dịch có hoạt động giống nhau không?

Tôi có nên sử dụng hay không?

+0

bản sao có thể có của [C++ Ảo/Ảo ảo được giải thích] (http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained) –

+0

@Harald: Không. Chủ đề khác nhau. – Xeo

+0

Nhưng tôi hỏi về việc sử dụng từ khóa đó. Không phải về phương pháp ảo trừu tượng. – kravemir

Trả lời

11

Bạn không thể ghi đè hàm thành viên mà không có nó.

Bạn chỉ có thể ẩn một.

struct Base { 
    void foo() {} 
}; 

struct Derived : Base { 
    void foo() {} 
}; 

Derived::foo không không override Base::foo; nó chỉ đơn giản ẩn nó bởi vì nó có cùng tên, như vậy mà sau:

Derived d; 
d.foo(); 

gọi Derived::foo.

virtual phép đa hình như vậy mà bạn thực chức năng ghi đè:

struct Base { 
    virtual void foo() {} 
}; 

struct Derived : Base { 
    virtual void foo() {} // * second `virtual` is optional, but clearest 
}; 

Derived d; 
Base& b = d; 
b.foo(); 

này gọi Derived::foo, bởi vì điều này bây giờ ghi đèBase::foo — đối tượng của bạn là đa hình.

(Bạn cũng có sử dụng tài liệu tham khảo hoặc gợi ý cho điều này, do the slicing problem.)


  • Derived::foo không cần phải lặp lại từ khóa virtualBase::foo đã sử dụng nó. Điều này được đảm bảo bởi tiêu chuẩn và bạn có thể dựa vào nó. Tuy nhiên, một số nghĩ rằng tốt nhất là giữ cho điều đó trong cho rõ ràng.
+2

Tôi biết rằng ảo là cần thiết khi khai báo phương thức có thể bị ghi đè. Tôi đã hỏi về việc sử dụng từ khóa này khi ghi đè phương thức, chứ không phải khai báo. – kravemir

+1

@Miro: Tôi không theo. Bạn ghi đè lên một hàm bằng cách khai báo một hàm khác ghi đè nó. Dù bằng cách nào, ít nhất thì đoạn cuối cùng của tôi cũng trả lời câu hỏi của bạn. –

8

Phương thức virtual trong lớp cơ sở sẽ xếp tầng thông qua phân cấp, làm cho mọi phương thức phân lớp có cùng chữ ký cũng virtual.

class Base{ 
public: 
    virtual void foo(){} 
}; 

class Derived1 : public Base{ 
public: 
    virtual void foo(){} // fine, but 'virtual' is no needed 
}; 

class Derived2 : public Base{ 
public: 
    void foo(){} // also fine, implicitly 'virtual' 
}; 

mặc dù tôi khuyên bạn nên viết virtual dù chỉ cho mục đích tài liệu.

5

Khi một hàm ảo, nó vẫn ảo trong toàn bộ hệ thống phân cấp, cho dù bạn có chỉ định rõ ràng mỗi khi nó là ảo hay không. Khi ghi đè phương thức, hãy sử dụng ảo để rõ ràng hơn - không có sự khác biệt nào khác :)

class A 
{ 
    virtual void f() 
    { 
     /*...*/ 
    }; 
}; 

class B:public A; 
{ 
    virtual void f() //same as just void f() 
    { 
     /*...*/ 
    }; 
}; 
Các vấn đề liên quan