2012-02-06 32 views
6

Chỉ mục vptr sẽ hiển thị tất cả các chức năng ảo, nhưng trong trường hợp của tôi chỉ có 2 trong số 3 chức năng ảo đang được hiển thị.Chức năng ảo không được liệt kê trong vptr

tôi cung cấp mã đầy đủ và các ảnh chụp màn hình dưới đây: -

ClassHeader.h

#include <iostream> 
using namespace std; 

// Employee Class 

class Employee 
{ 
    public : 
int salary ; 
Employee(){cout << "Inside CTOR" << endl;} 

virtual ~Employee() {cout << "Inside DTOR" << endl;} 

virtual void pay(){cout << "Employee" << endl;} 
}; 

// Manager Class 

class Manager : public Employee 
{ 
    public : 

virtual void pay(){cout<< "Manager pay" << endl;} 
virtual void Rank(){cout << "Manager Rank" << endl;} 
}; 

// JuniorManager Class 
class JuniorManager : public Manager 
{ 
    public : 

virtual void pay(){cout<< "JuniorManager pay" << endl;} 
virtual void Rank(){cout << "JuniorManager Rank" << endl;} 
}; 

main.cpp

#include "ClassHeader.h" 

void main() 
{ 
    Manager *p = new Manager(); 

p->pay(); 
p->Rank(); 

p = new JuniorManager(); 
p->Rank(); 

Employee *pE = dynamic_cast<Employee*>(p); 
pE->pay(); 

} 

Lớp Manager có hai chức năng ảo, thanh toán và Xếp hạng, nhưng chỉ trả tiền hiển thị trong vptr.

Ai đó có thể cho tôi biết, tại sao Xếp hạng không hiển thị, mặc dù chức năng ảo của nó.

Tôi đang sử dụng Visual Studio 2008 và với các bản cập nhật mới nhất, trên Windows 7 64 bit.

enter image description here

JuniorManager Debugger Ảnh chụp màn hình

Nó không hiển thị các chức năng ảo một trong hai. Vui lòng xem hình ảnh bên dưới.

enter image description here

+0

Visual studio cho chúng tôi biết _Base class của 'Manager' 'Employee'has 2 chức năng ảo: destructor và pay_. Chuyện gì vậy? – Lol4t0

+0

_void_ main()? C++ cho phép int main() và int main (int, char **). – Collin

Trả lời

2

Nếu bạn kiểm tra lớp như một nhân viên, vì lớp mà không có Rank(), nó sẽ không hiển thị Rank() trong vtable. Ảnh chụp màn hình của bạn hiển thị nội dung của lớp Employee.

"Yup, trình gỡ lỗi không có loại thông tin đủ để nói bao lâu mảng được. Vì vậy, nó chỉ hiển thị phần tử đầu tiên trừ khi ghi đè."

http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/23d4e48e-520e-45b4-8c2f-65c11946d75d

+2

Tôi đang khai báo một con trỏ tới một Người quản lý, không phải là một Nhân viên. Vui lòng xem mã hoàn chỉnh. –

+0

Nhưng cửa sổ thanh tra hiển thị lớp Employee. Ít nhất nội dung của bảng là chính xác theo nghĩa đó. – perreal

+0

Điều này có đúng không? Như tôi đã hiểu, nói chung, mỗi cá thể chỉ có một vtable, được sáp nhập từ chuỗi thừa kế của nó - đó là lý do tại sao chúng ta thấy 'const Manager :: 'vftable'' và không phải' const Employee ::' vftable''. Tôi không phải là một guru Visual Studio, nhưng nó sẽ đồng thời ẩn các chức năng ảo trong khi hiển thị các loại chính xác? – Matt

1

Có lẽ điều này là do quản lý được bắt nguồn từ nhân viên nhưng nhân viên không có một phương pháp Rank. Do đó khi một đối tượng Manager gọi Rank() nó sẽ không bao giờ cần phải nằm trong bảng ảo. Tôi đặt cược nếu bạn khởi tạo Xếp hạng JuniorManager sẽ nằm trong vtbl.

Để biết thêm chi tiết, hãy xem Does C++ virtual function call on derived object go through vtable? nhưng tôi tin rằng đây là lý do chính xác.

1

Tôi tin rằng đó là vì không có khả năng overriders nào của hàm Rank trong chuỗi kế thừa Manager của bạn, mặc dù nó là ảo. Nói cách khác, tôi nghĩ rằng lớp học của bạn phải biết các hàm ảo có thể ghi đè lên đúng cách để gửi cuộc gọi hàm, có nghĩa là việc triển khai phải lưu trữ các con trỏ tới các hàm ảo. Nếu không ai có thể ghi đè lên các hàm, không có sự mơ hồ trong công văn, và không có lý do gì để giữ một con trỏ khác trong vtable.

Bạn sẽ có thể xác minh bằng cách thực hiện chính xác cùng một bài tập này với cá thể JuniorManager của bạn: vì chúng ta cần duy trì con trỏ đến hàm Rank của Manager trong trường hợp JuniorManager, vì chúng ta có hàm Rank được ghi đè, chúng ta sẽ thấy con trỏ ảo trong vidable của JuniorManager.

Bây giờ tôi rất tò mò.Bạn có thể kiểm tra điều này cho chúng tôi và báo cáo lại không?

0

Tôi nghĩ rằng những gì chúng ta đang thấy ở đây là một điều kỳ quặc kỳ lạ của Visual Studio mà tôi không thể giải thích.

tôi sao chép mã vào Visual Studio để xem những gì đang xảy ra và tôi thậm chí đã cố gắng thêm:

JuniorManager *p1 = new JuniorManager();

p1 được chứng minh là một JuniorManager mà là một lớp con của Manager, mà là một lớp con của Nhân viên.

Trong mọi trường hợp trình gỡ lỗi hoàn toàn nhận thức được loại tĩnh chính xác của các biến con trỏ loại động chính xác của các đối tượng được trỏ đến và loại chính xác của vtable và loại chính xác của các mục nhập trong vtable. Tuy nhiên, vtable chỉ hiển thị trong trình gỡ rối như là một phần của lớp cơ sở (Employee) và vì một lý do nào đó chỉ các mục nhập đã biết cho lớp cơ sở mới được hiển thị.

Sẽ mát mẻ hơn nếu nó hiển thị phần còn lại của các mục nhập.

0

Chuyển đổi thuộc tính liên kết Linker-> Optimization-> Tham chiếu đến/OPT: NOREF. Visual Studio loại bỏ các tham chiếu đến hàm không được sử dụng (không được định nghĩa). Với trình liên kết chuyển đổi này, không loại bỏ các tham chiếu đó.

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