2012-12-14 24 views
10

Tôi đang cố gắng để làm cho một số callbacks từ hàm thành viên và tất cả mọi thứ là ok cho đến khi tôi cố gắng sử dụng một lớp mẫu có nguồn gốc từ 2 lớp như đối tượng gọi lại khi tôi nhận được lỗi sau:Pointers cho các thành viên cơ quan đại diện

error C2440: 'reinterpret_cast' : Pointers to members have different representations; cannot cast between them 

Điều này báo hiệu cho tôi rằng các con trỏ hàm thành viên có các biểu diễn khác nhau (doh!)

Các biểu diễn này là gì? sự khác biệt giữa chúng là gì?

+0

Bạn có thể muốn xem 'std :: bind', có thể liên kết một hàm thành viên và một đối tượng, và 'std :: function' có thể lưu trữ kết quả gọi lại. – MSalters

+0

@MSalters Tôi chỉ đang thực hiện một số thử nghiệm để up-cast một số thứ (không an toàn, tôi biết - nhưng họ là thử nghiệm). – Felics

+0

'std :: function' là con đường để đi. – Puppy

Trả lời

16

Danny Kalev explains this quite nicely:

The Underlying Representation of Pointers to Members

Although pointers to members behave like ordinary pointers, behind the scenes their representation is quite different. In fact, a pointer to member usually consists of a struct containing up to four fields in certain cases. This is because pointers to members have to support not only ordinary member functions, but also virtual member functions, member functions of objects that have multiple base classes, and member functions of virtual base classes. Thus, the simplest member function can be represented as a set of two pointers: one holding the physical memory address of the member function, and a second pointer that holds the this pointer. However, in cases like a virtual member function, multiple inheritance and virtual inheritance, the pointer to member must store additional information. Therefore, you can't cast pointers to members to ordinary pointers nor can you safely cast between pointers to members of different types.

To get a notion of how your compiler represents pointers to members, use the sizeof operator. In the following example, the sizes of a pointer to data member and a pointer to a member function are taken. As you can see, they have different sizes, hence, different representations:

struct A 
{ 
int x; 
void f(); 
}; 
int A::*pmi = &A::x; 
void (A::*pmf)() = &A::f; 
int n = sizeof (pmi); // 8 byte with my compiler 
int m = sizeof (pmf); // 12 bytes with my compiler 

Note that each of these pointers may have a different representation, depending on the class in question and whether the member function is virtual.

2

Đây là một điều Microsoft: họ làm cho con trỏ tới hàm thành viên nhỏ trong một số trường hợp, với chi phí sản xuất các con trỏ tới hàm thành viên có cơ quan đại diện khác nhau, như bạn vừa thấy. Có một chuyển đổi ở đâu đó để tắt tính năng này, để tất cả các con trỏ tới các thành viên đều có cùng biểu diễn.

+0

Xem http://social.msdn.microsoft.com/Forums/en/vclanguage/thread/a9cfa5c4-d90b-4c33-89b1-9366e5fbae74 để có cuộc thảo luận và liên kết tương tự với các công tắc trình biên dịch. –

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