Từ 1 tới 6 trên tổng số 6 kết quả

Đề tài: Function Pointer trong Class, lỗi cannot convert from 'int (__cdecl *)(int)' to 'int (__thiscall Class::*)(int)'

  1. #1
    Ngày gia nhập
    07 2007
    Nơi ở
    TP.HCM
    Bài viết
    199

    Mặc định Function Pointer trong Class, lỗi cannot convert from 'int (__cdecl *)(int)' to 'int (__thiscall Class::*)(int)'

    Mình có đoạn code như vầy:
    C++ Code:
    1. class ClassA
    2. {
    3. public:
    4.     int (ClassA::*i)(int x); // con tro ham.
    5.  
    6.     int func1(int x, int (*pf)(int x))
    7.     {
    8.         i = pf; // báo loi dòng này.
    9.         return 0;
    10.     }
    11.  
    12. private:
    13.     int func2(int x)
    14.     {
    15.         return this -> *i(x);
    16.     }
    17.  
    18. };

    Tức là mình muốn lưu địa chỉ của hàm truyền vào từ func1, để cho các method khác trong classA dùng sau này, thì nó báo việc gán i = pf là không hợp lệ (calling conversion)
    Code:
    error C2440: '=' : cannot convert from 'int (__cdecl *)(int)' to 'int (__thiscall ClassA::*)(int)' There is no context in which this conversion is possible
    Mình phải sửa như thế nào đây? Các bạn giúp mình.
    Mình thấy có nhiều tài liệu ít đề cập tới con trỏ hàm, hoặc có nhưng sơ sài.

  2. #2
    Ngày gia nhập
    10 2007
    Bài viết
    9

    Việc gán biến trỏ hàm sai là do bạn đã sử dụng sai kiểu con trỏ. Nếu như trong C, mọi thứ đều là toàn cục, ta có thể tham chiếu bằng cách include thì trong C++ mỗi lớp có ngữ cảnh của nó, các hàm trong lớp này không thể gọi khi ta đang trong ngữ cảnh của lớp khác hoặc toàn cục nếu ko static. Điều này phân biệt int (__cdecl *)(int), một con trỏ hàm nhận int trả về int, với int (__thiscall ClassA::*)(int), con trỏ của hàm trong ClassA nhận int trả về int. Nếu bạn muốn dùng hàm toàn cục thì khai báo biến i bằng :
    Code:
    int (*i)(int)
    , ngược lại, muốn dùng hàm trong ClassA thì khai báo hàm :
    Code:
    int func1(int (ClassA::*pf)(int))
    .
    Để tiện dụng ta có thể dùng typedef :
    Code:
    typedef int (*INT_FP)(int);
    typedef int (ClassA::*A_INT_FP)(int);

  3. #3
    Ngày gia nhập
    07 2007
    Nơi ở
    TP.HCM
    Bài viết
    199

    Cảm ơn bạn, mình làm theo bạn thì OK rồi.

    Nhưng nếu khai báo i và func thành static thì lỗi, như sau:
    C++ Code:
    1. class ClassA
    2. {
    3. public:
    4.     static int (*i)(int x);
    5.  
    6.     static int func(int x, int (*pf)(int x))
    7.     {
    8.     i = pf;
    9.         return 0;
    10.     }
    11.  
    12.  
    13. private:
    14.     static int func2(int x)
    15.     {
    16.         return (*i)(x);
    17.     }
    18. };
    19.  
    20. [B]int ClassA::i = 0;[/B] //nó báo lỗi dòng này
    21.  
    22. int main()
    23. {
    24.    return 1;
    25. }
    Lỗi như sau
    Code:
    error C2373: 'public: static int (__cdecl* ClassA::i)(int)' : redefinition; different type modifiers
    Cho dù thay dòng cuối thành
    int ClassA::*i(int) = 0;, hay
    int (ClassA::*i)(int) = 0; thì cũng lỗi:-??

  4. #4
    Ngày gia nhập
    07 2007
    Bài viết
    41

    Máy không còn C++ nên không test được, nhưng nghĩ phải là
    int (*(ClassA::i))(int) = 0; chứ nhỉ

  5. #5
    Ngày gia nhập
    07 2007
    Nơi ở
    TP.HCM
    Bài viết
    199

    Cũng lỗi à bạn ơi! :(

  6. #6
    Ngày gia nhập
    10 2007
    Bài viết
    9

    Smile Function Pointer trong Class, lỗi cannot convert from 'int (__cdecl *)(int)' to 'int (__thiscall Class::*)(int)'

    Trích dẫn Nguyên bản được gửi bởi MATH-INFO Xem bài viết
    Lỗi như sau
    Code:
    error C2373: 'public: static int (__cdecl* ClassA::i)(int)' : redefinition; different type modifiers
    Cho dù thay dòng cuối thành
    int ClassA::*i(int) = 0;, hay
    int (ClassA::*i)(int) = 0; thì cũng lỗi:-??
    Dĩ nhiên vậy sai là phải, bạn ko để ý là lỗi gì à ? Đây là lỗi redefinition, tức là bạn đã định nghĩa lại biến. Trong ClassA bạn đã khai báo static biến i là con trỏ hàm thì có nghĩa là nó sẽ tồn tại trên toàn cục, câu lệnh dưới bạn đã khai báo lại :
    Code:
    int ClassA::i = 0; //nó báo lỗi dòng này
    , nó lại trở thành biến int là một kiểu khác => lỗi different type modifiers, nếu bạn muốn thế thì phải bỏ khai báo int đi mà chỉ đơn thuần là gán thôi, vì i đã được định nghĩa (0 cũng có nghĩa là NULL, con trỏ hàm null). Hơn nữa, bạn chú ý một điều là khi hàm được khai báo static trong lớp, nó chỉ có nghĩa là được bao trong namespace của lớp đó, nó sẽ có hiệu lực toàn cục, giá trị của nó sẽ như một con trỏ hàm bình thường mà không cần có ngữ cảnh. Trong bài viết lần trước code bạn viết đã gần đúng, nếu bạn chọn cách nào thì chỉ cần sửa phần tương ứng và hãy giữ nguyên phần còn lại, chứ không nhất thiết phải có static. Thân.

Các đề tài tương tự

  1. Con trỏ hàm trong C/C++ - Function Pointer
    Gửi bởi Kevin Hoang trong diễn đàn Thủ thuật, Tutorials và Mã nguồn C/C++/C++0x
    Trả lời: 7
    Bài viết cuối: 16-10-2012, 01:28 PM
  2. Truyền array pointer 2 chiều vào function ?
    Gửi bởi vietwow trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 2
    Bài viết cuối: 13-04-2011, 10:12 PM
  3. Cách dùng function pointer trong hàm hook?
    Gửi bởi Kỳ Nam trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 5
    Bài viết cuối: 13-07-2009, 03:32 PM
  4. [ Solved ]Hỏi về phương thức trong lớp (class )!
    Gửi bởi camping29 trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 3
    Bài viết cuối: 07-10-2008, 03:31 PM
  5. [ Solved ]Hỏi về lớp bao(wrapped class) trong C++
    Gửi bởi redzeus02468 trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 18
    Bài viết cuối: 20-09-2008, 08:23 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn