2011-10-31 12 views
14

Mam program w C++C++. Błąd: void nie jest wskaźnikiem do obiektu typu

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"; 
    } 
}; 

Na kompilacji wyrzuca błąd:

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

Może ktoś wyjaśnić, co robię źle wytworzyć ten błąd?

+0

Tak, jest. Czy próbowałeś podać 'args' innym typom danych? – Blender

+2

Nie masz żadnych "abstrakcyjnych typów" (zakładam, że masz na myśli abstrakcyjne klasy bazowe) w tym przykładzie. Prawdopodobnie masz na myśli '* (argumenty *) args', które rzuca' args' z 'void *' na 'arguments *', następnie je dereferencje. Twój obecny kod próbuje dereferencji "void *" (co jest nielegalne), a następnie przesyła wartość dereferencji do 'arguments *', co prawie na pewno nie jest tym, co zamierzałeś. –

+0

@ Chr. Tak, właśnie to chciałem zrobić, dziękuję za wyjaśnienia. Btw, myślałem, że klasy i klasy zostały uznane za typy abstrakcyjne, podczas gdy np. int, float nie są abstrakcyjne. –

Odpowiedz

17

Jesteś dereferencja void * przed odlewaniem go konkretny typ. Musisz zrobić to na odwrót:

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

Ta kolejność jest istotna, ponieważ kompilator nie wie, jak stosować * do args (co jest void * i nie można dereferencjonowane). Twój numer (arguments *) mówi, co zrobić, ale jest już za późno, ponieważ dereferencja już zaszła.

+1

Ale proszę użyj "static_cast" tutaj - w ten sposób otrzymasz lepszy komunikat o błędzie ... –

+0

@Billy co robi 'static_cast'? –

+1

@Matt: To samo, co casting w stylu C, z wyjątkiem bardziej ograniczonych. 'static_cast' uniemożliwia usunięcie' const', reinterpretację typu wskaźnika i kilka innych nieprzyjemnych rzeczy. Ogólnie mówiąc, wszystko, co 'static_cast's działa na platformach/architekturach. Więcej szczegółów znajduje się w sekcji 5.2.9 standardu C++ (zakładając, że C++ 03) –

3

Masz * w niewłaściwym miejscu. Więc próbujesz wyłuskać void*. Spróbuj to zamiast:

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

Alternatywnie, można to zrobić: (co pozwala również na uniknięcie kopiowania-konstruktora - jak wspomniano w komentarzach)

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

Pozostawienie go jako wskaźnika jest prawdopodobnie lepsze, ponieważ pozwala uniknąć konstruktora kopiowania. Jednak OP powinien uczynić wskaźnik (zarówno 'argumenty *' jak i 'void *') 'const'. –

0

* args oznacza "obiekt (wartość) args wskazuje na". Dlatego nie można go rzucić jako wskaźnika do obiektu (argumentu). Dlatego to daje error

4

szkielety przykład odtworzyć powyższy błąd:

#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 
} 

Powyższy kod jest niewłaściwy, ponieważ stara się nieprawidłowego wskaźnika do pustki. To nie jest dozwolone.

Teraz uruchom następny kod poniżej. Jeśli rozumiesz, dlaczego poniższy kod działa, a powyższy kod go nie zawiera, będziesz lepiej przygotowany do zrozumienia, co dzieje się pod maską.

#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

problemu, bdonlan mówi się "dereferencing void* przed odlewaniem."

myślę, że ten przykład pomoże:

#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; 
} 
Powiązane problemy