2011-10-31 32 views
14

Tôi có một ++ chương trình C:C++. Lỗi: void không phải là một loại con trỏ-to-object

struct arguments 
{ 
    int a, b, c; 
    arguments(): a(3), b(6), c(9) {} 
}; 

class test_class{ 
    public: 

    void *member_func(void *args){ 
     arguments vars = (arguments *) (*args); //error: void is not a 
               //pointer-to-object type 

     std::cout << "\n" << vars.a << "\t" << vars.b << "\t" << vars.c << "\n"; 
    } 
}; 

On biên dịch nó ném một lỗi:

error: ‘void*’ is not a pointer-to-object type 

Ai đó có thể giải thích những gì tôi đang làm sai tạo ra lỗi này?

+0

Vâng, có. Bạn đã thử cho 'args' một kiểu dữ liệu khác chưa? – Blender

+2

Bạn không có bất kỳ "loại trừu tượng nào" (tôi giả sử bạn có nghĩa là các lớp cơ sở trừu tượng) trong ví dụ này. Bạn có thể có nghĩa là '* (arguments *) args', trong đó phôi' args' từ 'void *' thành 'arguments *', _then_ dereferences nó. Mã hiện tại của bạn sẽ cố gắng dereference một 'void *' (đó là bất hợp pháp), sau đó đúc giá trị dereferenced đến một 'đối số *', mà gần như chắc chắn không phải là những gì bạn dự định. –

+0

@ Chris Vâng đó là những gì tôi đã cố gắng để làm, nhờ làm rõ. Btw, tôi nghĩ rằng cấu trúc và các lớp học được coi là các loại trừu tượng trong khi ví dụ. int, float không trừu tượng. –

Trả lời

17

Bạn đang dereferencing các void * trước khi đúc nó để một loại bê tông. Bạn cần phải làm điều đó theo cách khác xung quanh:

arguments vars = *(arguments *) (args); 

trật tự này rất quan trọng, bởi vì trình biên dịch không biết làm thế nào để áp dụng *-args (mà là một void * và không thể được dereferenced). (arguments *) của bạn sẽ cho bạn biết phải làm gì, nhưng đã quá muộn, bởi vì sự dereference đã xảy ra.

+1

Nhưng hãy sử dụng 'static_cast' ở đây - bạn sẽ nhận được thông báo lỗi tốt hơn theo cách đó ... –

+0

@Billy' static_cast' làm gì? –

+1

@Matt: Tương tự như dàn diễn viên kiểu C, ngoại trừ hạn chế hơn. 'static_cast' không cho phép xóa' const', diễn giải lại kiểu con trỏ và một vài thứ khó chịu khác. Nói chung, bất cứ điều gì 'static_cast' sẽ làm việc trên nền tảng/kiến ​​trúc. Xem phần 5.2.9 của tiêu chuẩn C++ để biết thêm chi tiết (giả sử C++ 03) –

3

Bạn có * ở địa điểm sai. Vì vậy, bạn đang cố gắng dereference các void*. Hãy thử điều này thay vì:

arguments vars = *(arguments *) (args); 
std::cout << "\n" << vars.a << "\t" << vars.b << "\t" << vars.c << "\n"; 

Ngoài ra, bạn có thể làm điều này: (mà cũng tránh được sao chép constructor - như đã đề cập trong các ý kiến)

arguments *vars = (arguments *) (args); 
std::cout << "\n" << vars->a << "\t" << vars->b << "\t" << vars->c << "\n"; 
+0

Để nó như một con trỏ có lẽ tốt hơn, vì nó tránh được một hàm tạo bản sao. Tuy nhiên, OP sẽ tạo con trỏ (cả hai 'arguments *' và 'void *') 'const'. –

0

* args có nghĩa là "đối tượng (giá trị) args trỏ tới". Vì vậy, nó không thể được đúc như con trỏ đến đối tượng (đối số). Đó là lý do tại sao nó được đưa ra lỗi

4

xương Bare ví dụ để sao chép các lỗi trên:

#include <iostream> 
using namespace std; 
int main() { 
    int myint = 9;    //good 
    void *pointer_to_void;  //good 
    pointer_to_void = &myint; //good 

    cout << *pointer_to_void; //error: 'void*' is not a pointer-to-object type 
} 

Đoạn mã trên là sai vì nó đang cố gắng dereference một con trỏ đến một khoảng trống. Điều đó không được phép.

Bây giờ hãy chạy mã tiếp theo bên dưới, Nếu bạn hiểu tại sao mã sau chạy và mã trên không, bạn sẽ được trang bị tốt hơn để hiểu những gì đang diễn ra dưới mui xe.

#include <iostream> 
using namespace std; 
int main() { 
    int myint = 9; 
    void *pointer_to_void; 
    int *pointer_to_int; 
    pointer_to_void = &myint; 
    pointer_to_int = (int *) pointer_to_void; 

    cout << *pointer_to_int; //prints '9' 
    return 0; 
} 
0

Vấn đề như bdonlan nói là "dereferencing void* trước khi truyền".

Tôi nghĩ rằng ví dụ này sẽ giúp đỡ:

#include <iostream> 

using namespace std; 

int main() 
{ 



    void *sad; 
    int s = 23; 
    float d = 5.8; 

    sad = &s; 
    cout << *(int*) sad;//outputs 23//wrong: cout << *sad ;//wrong: cout << (int*) *sad; 



    sad = &d; 
    cout << *(float *) sad;//outputs 5.8//wrong: cout << *sad ;//wrong: cout << (float*) *sad; 

    return 0; 
} 
Các vấn đề liên quan