2017-02-22 19 views
8

Tôi gặp khó khăn khi gọi một con trỏ tới một hàm thành viên trên một đối tượng được truyền từ void*. Xem ví dụ bên dưới:Không thể gọi con trỏ đến hàm thành viên từ phương thức tĩnh

class Test 
{ 
public: 
    Test(int pointTo) 
    { 
     if (pointTo == 1) 
      function = &Test::Function1; 
     else 
      function = &Test::Function2; 
    } 

    static void CallIt(void* cStyle) 
    { 
     Test* t(static_cast<Test*>(cStyle)); 
     (t->*function)();// error C2568: '->*': unable to resolve function overload 
    } 

    void CallIt() 
    { 
     (this->*function)();// Works just fine 
    } 

private: 
    typedef void (Test::*ptrToMemberFunc)(); 

    ptrToMemberFunc function; 

    void Function1() 
    { 
     std::cout << "Function 1" << std::endl; 
    } 

    void Function2() 
    { 
     std::cout << "Function 2" << std::endl; 
    } 
}; 

int main() 
{ 
    Test t1(1); 
    Test t2(2); 

    Test::CallIt(static_cast<void*>(&t1)); 
    Test::CallIt(static_cast<void*>(&t2)); 

    t1.CallIt(); 
    t2.CallIt(); 

    return 0; 
} 

Điều gì xảy ra khi đối tượng được đúc thành void* và ngược lại? Tại sao tôi không còn có thể gọi con trỏ đến chức năng thành viên?

EDIT:

Sửa đổi CallIt() như sau cho phép các chương trình để biên dịch, nhưng tôi vẫn tò mò là tại sao ban đầu đã không làm việc.

static void CallIt(void* cStyle) 
{ 
    Test* t(static_cast<Test*>(cStyle)); 
    Test::ptrToMemberFunc pf(t->function); 
    (t->*pf)(); 
} 
+0

đó là hài hước mà tôi chỉ viết chính xác cùng một mã trong wandbox, xuống identificatiors. Câu trả lời của Tuple_cat giải thích điều này. Về cơ bản bạn phải liên kết đối tượng và có thể gọi được, do đó, một toán tử vô hướng là không đủ. Một số trình biên dịch cung cấp thông báo lỗi dễ hiểu hơn, giống như chúng cho bạn biết rằng bạn chỉ có thể gọi thành viên tĩnh theo cách này - gợi ý rằng bạn không có con trỏ này cho chúng – Swift

+0

Về chỉnh sửa của bạn, tôi chỉ nghĩ giao diện của toán tử '- > * 'đang ném bạn đi. Xem xét nó chỉ là một hàm bình thường có tên 'call_with_this', lấy một con trỏ tới một đối tượng và một hàm thành viên. Sau đó, cuộc gọi không làm việc ban đầu của bạn là 'call_with_this (t, function);'. Ở đây nó chỉ xảy ra tên 'function' là một thành viên không tĩnh của lớp' Test', nhưng nó không liên quan gì đến 't'. Và bởi vì bạn đang ở trong một hàm tĩnh, không có 'this' để tìm trong để giải quyết tên' function'. Khi bạn yêu cầu 't-> function', bạn có một giá trị thực với một tên có thể truy cập. – GManNickG

+0

@GManNickG Chính xác là như vậy. Bây giờ tôi thấy giải pháp, tôi nhận được nó, nhưng tôi đã không nhận ra những gì toán tử '-> *' thực sự đang làm (tôi đã đọc nó như là '(t -> (* function))'). – Kerry

Trả lời

10
main.cpp:17:14: error: invalid use of member 'function' in static member function 
     (t->*function)();// error C2568: '->*': unable to resolve function overload 
      ^~~~~~~~ 

function là thành viên dữ liệu không tĩnh, vì vậy bạn không thể truy cập nó từ một hàm tĩnh.

Nếu bạn muốn tham khảo t 's function, bạn có thể làm điều đó như vậy:

 (t->*(t->function))(); 
+0

Đó là lý do tương tự tại sao anh ta buộc phải viết '(this -> * function)()' trong thành viên không tĩnh, toán tử gián tiếp bên trong "được" giá trị của con trỏ, trong khi ngoài cùng cho phép gọi tham chiếu đến đối tượng – Swift

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