2013-05-10 30 views
6

Zajmowałem się tym przez kilka godzin, bezskutecznie. Zasadniczo mamBłąd: przyjmowanie adresu tymczasowego [-fprissive]

struct rectangle { 
    int x, y, w, h; 
}; 

rectangle player::RegionCoordinates() // Region Coord 
{ 
    rectangle temp; 
    temp.x = colRegion.x + coordinates.x; 
    temp.w = colRegion.w; 
    temp.y = colRegion.y + coordinates.y; 
    temp.h = colRegion.h; 

    return temp; 
} 

// Collision detect function 
bool IsCollision (rectangle * r1, rectangle * r2) 
{ 
    if (r1->x < r2->x + r2->w && 
     r1->x + r1->w > r2->x && 
     r1->y < r2->y + r2->h && 
     r1->y + r1->h > r2->y) 
     { 
      return true; 
     } 
    return false; 
} 

//blah blah main while loop 
if (IsCollision(&player1.RegionCoordinates(), &stick1.RegionCoordinates())) //ERROR 
{ 
    player1.score+=10; 
    stick1.x = rand() % 600+1; 
    stick1.y = rand() % 400+1; 
    play_sample(pickup,128,128,1000,false); 
} 

Wszelkie pomysły? Jestem pewien, że jest to coś naprawdę oczywistego, ale nie potrafię tego zrozumieć.

+2

Jaki jest podpis "RegionCoordinates()"? – Angew

+0

lol Zrobiłem, mój zły –

Odpowiedz

1

Biorąc pod uwagę rodzaj błędu otrzymujesz muszę zakładać RegionCoordinates() zwraca obiekt przez wartość, powodując utworzenie tymczasowego, a pacjent jest adres że tymczasowy.

Adres-wykonawcy wymaga użycia lwartość jako jej argumentu, ale starasz się go do rvalue (uzupełnienia tymczasowe są rvalues ​​).

Można to zrobić (jeśli nie używasz C++ 11, wymienić auto z typem zwracanej przez RegionCoordinates):

auto rcPlayer1 = player1.RegionCoordinates(); 
auto rcStick1 = player1.RegionCoordinates(); 
if (IsCollision(&rcPlayer1, &rcStick1)) //ERROR 
{ 
    player1.score+=10; 
    stick1.x = rand() % 600+1; 
    stick1.y = rand() % 400+1; 
    play_sample(pickup,128,128,1000,false); 
} 

Alternatywnie, można zmienić IsCollision tak, że przyjmuje referencje raczej niż wskaźniki, as suggested by Angew in his answer.

3

Od IsCollision trwa rectangle * i biorą adres wyniku tutaj:

if (IsCollision(&player1.RegionCoordinates(), &stick1.RegionCoordinates())) 

Najprawdopodobniej wracają do rectangle z powrotem RegionCoordinates() która jest tymczasowa zmienna, ponieważ zniknie po oświadczeniu if skończone. Jeśli przypiszesz wynik RegionCoordinates() do zmiennej to nie będzie tymczasowa i można następnie podjąć adres to:

rectangle r1 = player1.RegionCoordinates() ; 
rectangle r2 = stick1.RegionCoordinates() ; 
if (IsCollision(&r1, &r2)) 

Ewentualnie można wziąć parametry jak const odniesień, które byłyby bardziej C++ Sposób wykonania:

bool IsCollision (const rectangle &r1, const rectangle &r2) 
10

RegionCoordinates() zwraca obiekt według wartości. Oznacza to, że wywołanie RegionCoordinates() zwraca tymczasową instancję z rectangle. Jak informuje błąd, próbujesz pobrać adres tego tymczasowego obiektu, co nie jest legalne w C++.

Dlaczego mimo to IsCollision() pobiera wskaźniki? Bardziej naturalne byłoby przyjmowanie jego parametrów przez odniesienie do:

bool IsCollision (const rectangle &r1, const rectangle &r2) { 
if (r1.x < r2.x + r2.w && 
    r1.x + r1.w > r2.x && 
    r1.y < r2.y + r2.h && 
    r1.y + r1.h > r2.y) { 
     return true; 
    } 
     return false; 
} 
//blah blah main while loop 
if (IsCollision(player1.RegionCoordinates(), stick1.RegionCoordinates())) //no error any more 
{ 
player1.score+=10; 
stick1.x = rand() % 600+1; 
stick1.y = rand() % 400+1; 
play_sample(pickup,128,128,1000,false); 
}