2010-10-27 21 views
5

Điều này vừa mới nhảy vào đầu tôi và tôi không thể đoán được nó.Trình biên dịch xác định vị trí của thành viên khi truy cập thông qua con trỏ cơ sở

Nếu tôi có một mã như thế này:

struct A { char x[100]; }; 

struct B { int data; }; 

struct C : A, B {}; 

#include <iostream> 
using namespace std; 

B* get_me_some_stuff() 
{ 
     static int x = 0; 
     if (++x % 2 == 0) 
       return new B(); 
     else 
       return new C(); 
} 

int main() 
{ 
     B* x = get_me_some_stuff(); 
     B* y = get_me_some_stuff(); 

     x->data = 10; 
     y->data = 20; 

     cout << x->data << " " << y->data << endl; 

     return 0; 
} 

Làm thế nào để trình biên dịch xác định vị trí bộ nhớ của data thành viên?

Trả lời

2

Hãy thử điều này:

C* x = new C(); 
B* y = x; 
cout << x << " " << y << endl; 

Đầu ra cho tôi:

0x1ae2010 0x1ae2074 

hành động đúc C*-B* (hoặc theo một hướng khác) bao gåm es số học con trỏ cần thiết.

4

Con trỏ x và y của bạn thực sự trỏ đến đối tượng con B của đối tượng B và C (sử dụng loại có nguồn gốc cao nhất).

Example:

int main() { 
    C c; 
    B *pb = &c; // converting the pointer here actually adjusts the address 

    void *pvc = &c; // doesn't adjust, merely type conversion 
    void *pvb = pb; // doesn't adjust, merely type conversion 

    cout << boolalpha; 
    cout << (pvc == pvb) << '\n'; // prints false 
    cout << (&c == pb) << '\n'; // prints true! 
           // (&c is converted to a B* for the comparison) 

    C *pc = static_cast<C*>(pb); // this static_cast, which is UB if pb doesn't 
    // actually point to a C object, also adjusts the address 

    cout << (pc == &c) << '\n'; // prints true 

    return 0; 
} 

Các đạo đức của câu chuyện này? Sử dụng static_cast từ void * (không reinterpret_cast), và bạn chỉ có thể chuyển đổi từ khoảng trống để cùng loại chính xác mà ban đầu được sử dụng để chuyển đổi sang làm mất hiệu lực:

reinterpret_cast<C*>(pvb) // undefined behavior 
Các vấn đề liên quan