2010-03-31 42 views
7

Bảng ảo nào sẽ là chức năng ảo thuần túy? Trong lớp cơ sở hoặc lớp dẫn xuất?Chức năng ảo thuần túy nằm ở đâu trong C++?

Ví dụ: bảng ảo trông như thế nào trong mỗi lớp?

class Base { 

    virtual void f() =0; 
    virtual void g(); 
} 


class Derived: public Base{ 

    virtual void f(); 
    virtual void g(); 

} 
+0

câu hỏi liên quan: http://stackoverflow.com/questions/2549618/ –

+0

Ai nói có một bảng ảo? Các tiêu chuẩn nói gì về họ và như vậy họ là một figment của trí tưởng tượng của người dân :-) Nếu bạn muốn trình biên dịch cụ thể chi tiết thực hiện bạn cần phải đề cập đến trình biên dịch bạn đang sử dụng. –

Trả lời

15

g++ -fdump-class-hierarchy layout.cpp tạo tệp layout.cpp.class. Nội dung của layout.cpp.class sẽ hiển thị như sau:

 
Vtable for Base 
Base::_ZTV4Base: 4u entries 
0  (int (*)(...))0 
8  (int (*)(...))(& _ZTI4Base) 
16 __cxa_pure_virtual 
24 Base::g 

Class Base 
    size=8 align=8 
    base size=8 base align=8 
Base (0x7ff893479af0) 0 nearly-empty 
    vptr=((& Base::_ZTV4Base) + 16u) 

Vtable for Derived 
Derived::_ZTV7Derived: 4u entries 
0  (int (*)(...))0 
8  (int (*)(...))(& _ZTI7Derived) 
16 Derived::f 
24 Derived::g 

Class Derived 
    size=8 align=8 
    base size=8 base align=8 
Derived (0x7ff893479d90) 0 nearly-empty 
    vptr=((& Derived::_ZTV7Derived) + 16u) 
    Base (0x7ff893479e00) 0 nearly-empty 
     primary-for Derived (0x7ff893479d90) 

Loại bỏ các 'thuần khiết' của f thay đổi dòng thứ năm tới:

 
16 Base::f 
+0

Thực sự thú vị:) –

+0

+1 Đẹp - đánh bại tất cả công việc đoán –

1

Mục nhập vtable sẽ nằm trong lớp cơ sở.

Tại sao? Bởi vì bạn có thể có một kiểu con trỏ cơ sở chứa một địa chỉ của đối tượng loại có nguồn gốc và vẫn gọi phương thức này trên biến con trỏ của kiểu cơ sở.

tinh khiết ảo chỉ đơn giản nói với trình biên dịch mà các loại có nguồn gốc phải cung cấp thực hiện riêng của họ, và họ không thể dựa vào các lớp cơ sở thực hiện (nếu thậm chí được quy định trong lớp cơ sở)

1

Trong cả hai thực sự. Lớp cơ sở vtable sẽ có một khe cho hàm ảo thuần túy trỏ đến một cái gì đó giống như pure_virtual_function_called() stub mà có lẽ sẽ hủy bỏ chương trình, trong khi lớp dẫn xuất vtable sẽ có một con trỏ đến việc thực hiện thực tế.

2

Mỗi lớp có vtable riêng. Mục nhập cho f trong Base sẽ là NULL và mục nhập trong Derived sẽ là một con trỏ đến mã cho phương thức được triển khai.

+1

Vâng, không thực sự NULL. Trong VC++, mục nhập là địa chỉ của hàm CRT _purecall: http://thetweaker.wordpress.com/2010/06/03/on-_purecall-and-the-overheads-of-virtual-functions/ –

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