MC, 14:29 sobota, 12.01.2013 r.
Ilustracja do artykułu: C++ - Rozwiązanie błędu: passing 'const ...' as '...' argument of '...' discards qualifiers

C++ - Rozwiązanie błędu: passing 'const ...' as '...' argument of '...' discards qualifiers

Oj dawno nie pisałem nic w C++. Także ostatnie zadanie jakie miałem do wykonania akurat w tym właśnie języku programowania, wymagało ode mnie sporo przypominania sobie dawniej dobrze znanych faktów. Z tego powodu pewnie pojawi się na łamach strony kilka krótkich notek w tym temacie. Dziś o prostym błędzie "error: passing ‘const ...’ as ‘...’ argument of ‘...’ discards qualifiers".

Co to za błąd i jak mu zaradzić?

Może i wynika to z jakiegoś niedorozwoju, ale często mam przypadłość, że oczywiste komunikaty kompilatora, takie jak ten zacytowany powyżej, dopiero wtedy stają się naprawdę oczywiste jak już rozwiążę problem. Wtedy dopiero widzę, że faktycznie... dokładnie to powiedziane było w treści błędu. No ale nic, może nie ja jeden nie od razu wpadnę na przekaz tego komunikatu ;)

A mówi on o tym, że próbujemy przesłać jakiś obiekt zadeklarowany ze słowem kluczowym const, czyli obiekt stały, jako parametr do innej funkcji, która wcale nie spodziewa się otrzymać parametru stałego, a przynajmniej tak wynika z jej deklaracji.
Może opisuję to dość nieklarowne, ale najczęściej sprowadza się to do przypadku, w którym z jednej funkcji stałej (w sensie nie zmieniającej otrzymanych argumentów), wywołujemy inną, która nie ma w sobie tego ograniczenia. Spójrzmy poniżej:

void FunkcjaDoWykonania(const JakasKlasa &obiekt)
{
// logika funkcji
obiekt.JakasMetod();
// dalsza logika
}

void JakasKlasa :: JakasMetoda()
{
// logika metody
}

Jak widzimy, z funkcji FunkcjaDoWykonania wywołujemy metodę obiektu JakasMetoda, przy czym obiekt ten został przyjęty jako argument z kwalifikatorem const, natomiast JakasMetoda w swojej definicji nie zawiera informacji o tym, że nie zmienia ona parametrów obiektu. Dlatego też kompilator przypuszcza, że właśnie tak zadziała jej logika i dlatego obwieszcza nam ten złowrogi komunikat z błędem.

Pewnie łatwo się domyślić, że drogi wyjścia z tego problemu są dwie. Albo zmieniamy parametry obiektu albo tego nie robimy. Jeżeli nie zmieniamy go, to wywoływaną metodę powinniśmy opatrzyć kwalifikatorem const:

void JakasKlasa :: JakasMetoda() const
{
// logika metody
}
Jeżeli zaś metoda ta ma zmieniać obiekt, na rzecz którego zostanie wywołana, powinniśmy zdjąć ograniczenie z funkcji FunkcjaDoWykonania:
void FunkcjaDoWykonania(JakasKlasa &obiekt)
{
// logika funkcji
obiekt.JakasMetod();
// dalsza logika
}

W moim wypadku najczęściej okazywało się, że przez roztargnienie zapominałem poinformować w deklaracji metody, że nie planuję modyfikować obiektu i stąd ten raban.

Komentarze (0) - Nikt jeszcze nie komentował - bądź pierwszy!

Imię:
Treść: