Tôi cần chuyển đổi một số con trỏ hàm thành viên sang số void*
con trỏ (vì tôi cần đẩy chúng vào ngăn Lua, nhưng vấn đề không liên quan đến Lua).Gọi con trỏ hàm thành viên C++: con trỏ này bị lỗi
Tôi thực hiện việc này bằng cách sử dụng union
. Nhưng khi tôi chuyển đổi các con trỏ hàm thành viên thành một số void*
và ngược lại và sau đó cố gắng gọi con trỏ với một thể hiện của lớp, con trỏ this
bị hỏng. Kỳ lạ thay, vấn đề này không xảy ra, nếu tôi chuyển đổi con trỏ void*
trở lại thành con trỏ hàm kiểu C với một con trỏ đến lớp đó là tham số đầu tiên của nó.
Dưới đây là đoạn mã mà chứng tỏ vấn đề:
#include <iostream>
using namespace std;
class test
{
int a;
public:
void tellSomething()
{
cout << "this: " << this << endl;
cout << "referencing member variable..." << endl;
cout << a << endl;
}
};
int main()
{
union
{
void *ptr;
void (test::*func)();
} conv1, conv2;
union
{
void *ptr;
void (*func) (test*);
} conv3;
test &t = *new test();
cout << "created instance: " << (void*) &t << endl;
// assign the member function pointer to the first union
conv1.func = &test::tellSomething;
// copy the void* pointers
conv2.ptr = conv3.ptr = conv1.ptr;
// call without conversion
void (test::*func1)() = conv1.func;
(t.*func1)(); // --> works
// call with C style function pointer invocation
void (*func3) (test*) = conv3.func;
(*func3) (&t); // --> works (although obviously the wrong type of pointer)
// call with C++ style member function pointer invocation
void (test::*func2)() = conv2.func;
(t.*func2)(); // `this' is the wrong pointer; program will crash in the member function
return 0;
}
Đó là kết quả:
created instance: 0x1ff6010
this: 0x1ff6010
referencing member variable...
0
this: 0x1ff6010
referencing member variable...
0
this: 0x10200600f
referencing member variable...
zsh: segmentation fault (core dumped) ./a.out
Đây có phải là một lỗi trong trình biên dịch (GCC)? Tôi biết rằng sự chuyển đổi này giữa các con trỏ hàm void*
và (thành viên) không tuân thủ tiêu chuẩn, nhưng điều kỳ lạ là nó hoạt động khi chuyển đổi void*
thành con trỏ hàm kiểu C.
Bạn đã kiểm tra sizeof() của memfunptr chưa? Trong thực hiện của tôi nó lớn hơn sizeof (void *) – PlasmaHH