2013-06-14 54 views
7

Vì tất cả chức năng ảo trong C++ đều được lưu trong bảng V. Overiding diễn ra trong trường hợp chức năng ảo. Tôi muốn hỏi có bất kỳ cách nào mà chúng ta có thể gọi hàm ảo trực tiếp từ bảng và có thể quá xác định những gì hàm V-bảng chứa.Gọi chức năng ảo từ bảng V

+0

Tại sao một người muốn làm điều đó? Ít nhất bạn có thể (sử dụng một số địa chỉ bộ nhớ trực tiếp), miễn là bạn biết về nội tại của trình biên dịch ABI của bạn. –

+0

chúng ta có thể làm gì đó với V-con trỏ có trong Class (nếu lớp chứa các hàm ảo) trỏ đến v-table.using g ++ compiler, tôi đã thử với con trỏ V nhưng nó không hoạt động. –

Trả lời

16

Thực ra bạn có thể. Tôi không quan tâm về tính di động, nhưng trong VS bạn có thể làm điều đó. Giả sử rằng chúng tôi đang xây dựng mã 32 bit với VS, 4 byte đầu tiên tại địa chỉ đối tượng là địa chỉ vtable. Bằng cách xem các tệp tiêu đề, chúng ta biết thứ tự các phương thức trong vtable.

Ví dụ:

class Base 
{ 
public: 

    virtual void printMessage() 
    { 
     std::cout << "Base::printMessage()" << std::endl; 
    } 
}; 

class Derived : public Base 
{ 
public: 

    void printMessage() 
    { 
     std::cout << "Derived::printMessage()" << std::endl; 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    Derived d; 

    unsigned int vtblAddress = *(unsigned int*)&d; 

    typedef void(*pFun)(void*); 

    pFun printFun = (pFun)(*(unsigned int*)(vtblAddress)); 

    printFun(&d); 

    return 0; 
} 

T.B. Tôi sẽ không hỏi tại sao bạn làm điều đó, nhưng ở đây bạn có một tùy chọn :-)

+1

điều này thực sự là tôi muốn. –

+8

Không thể tin được, Peter Wood, Eelke, toro2k, Stony và quetzalcoatl không thể biết được những gì đang được hỏi ở đây. Làm thế nào để mọi người tham gia trong chủ đề này hiểu những gì đang được hỏi? 5 "Smart" guys với danh tiếng khá thấp so với Mike Seymour và ForEveR đang vặn vẹo mọi người khác. Ý tôi là, bạn không hiểu câu hỏi, điều đó là tốt, nhưng hãy để những người khác thảo luận về nó vì lợi ích của chúa ... – user1764961

+1

@ user1764961- yaa người đàn ông thực sự không thể tin nổi !! –

2

Không đảm bảo theo tiêu chuẩn, các chức năng ảo được triển khai bằng cách sử dụng v-table. Vì vậy, chỉ khi bạn chắc chắn, trình biên dịch đó sử dụng v-table - bạn có thể tìm thấy bù đắp cần thiết.

+1

Trong c + + là nó không cần thiết mà trình biên dịch sẽ sử dụng V-bảng để thực hiện chức năng ảo? –

+0

@ user2484070 có, không cần thiết. Việc thực hiện các hàm ảo phụ thuộc vào trình biên dịch. – ForEveR

+0

@ user2484070, các giá trị sẽ được lưu trữ ở đâu đó và bằng cách nào đó, đó là chắc chắn. Nó sẽ là một cái bàn V nổi tiếng hay cái gì đó khác ... không thực sự quan trọng. – user1764961

2

Có thể, không. Ngôn ngữ không chỉ định cách gửi công văn ảo, chỉ cách nó hoạt động. Nó không nhất thiết phải được thực hiện bằng cách sử dụng một bảng v, và không có cách nào để truy cập một chức năng ảo ngoại trừ việc gọi nó.

Nếu bạn chỉ cần hỗ trợ một ABI cụ thể, bạn có thể sử dụng chi tiết triển khai, cùng với một số phôi con trỏ tinh tế, để ánh xạ đối tượng tới con trỏ hàm theo cùng cách mà cơ chế gửi đi ảo thực hiện. Nhưng bạn sẽ bước ra ngoài ngôn ngữ được xác định vào lãnh thổ không được hỗ trợ, không di động, vì vậy tôi chắc chắn sẽ khuyên bạn nên suy nghĩ lại những gì bạn đang cố gắng làm.

+1

hiểu rồi. cảm ơn :) –

0

Tôi muốn nói không nói chung, bởi vì việc triển khai chính xác vtable là một nền tảng/trình biên dịch cụ thể. Nếu bạn biết làm thế nào nền tảng/trình biên dịch thực hiện vtable và addresation, nó có thể có thể tính toán nó bằng cách xác định địa chỉ của vtable cho một lớp cụ thể và sau đó thêm một offset của một phương thức ảo.

Vtable chứa tất cả các phương thức ảo cho lớp. Bạn có thể tháo rời ứng dụng để xem chúng.

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