Wpis z mikrobloga

@FantaZy: NIE.
@Xonar: Nie wprowadzaj ludzi w błąd.

Po pierwsze, jeżeli mówimy o typach prostych (int) to zarówno const jak i final jest bezsensowne, bo wartość tak czy inaczej jest kopiowana. To tak na marginesie.

Ogólnie, działanie final w Javie jest zupełnie inne niż działanie const w C++.

const - zapewnia stałą wartość
final - zapewnia stałą referencję

To znaczy, że jak w C++ przyjmiesz stałą referencję na obiekt klasy
@CamelCase: czy const dla typów prostych jest bezsensowny? Jeżeli mamy funkcję foo( int const A ) to wyraźnie zaznaczamy, że nie powinno się zmieniać wartości A. Może to uchronić np przed pomyleniem operatorów = i ==.
@Mongoloid: Hmm, albo foo(const int) albo foo(const A&). Coś Ci się pomieszało z tą konstrukcją.

Odpowiadając na pytanie, moim zdaniem jest bezsensowny. Deklaracja foo(const A& a) mam za zadanie zdefiniować kontrakt. To znaczy, że zapewnia Cię, że funkcja foo nie zmieni obiektu a który jej podasz, możesz to zrobić bezpiecznie.

Deklaracja foo(const int n) nie niesie żadnej informacji dodanej w stosunku do foo(int n). Bo n, którego Ty użyjesz w metodzie
o nie możesz zmienić jego stanu, na przykład ustawić jakiegoś pola


@CamelCase: mozesz, jesli klasa obiektu ma pola mutable:

class Klass{
public:
mutable int x=0;
};

void tester(const Klass& klass){
klass.x = 3;
}
@afe1: Jeszcze nigdy nie widziałem publicznego pola typu mutable, a parę ładnych lat w C++ programuję (zawodowo). Zazwyczaj używa się ich do muteksów i semaforów oraz do memoizacji. Właściwie to nie znam innych zastosowań.
@CamelCase: kontrukcja jest dobra, const może być z obu stron typu. ;)

Co do dalszej części wypowiedzi- nie rozumiem, co mi się nie skompiluje? Bez const mogę przypisywać i porównywać, z constem kompilator nie pozwoli przypisać. Jeżeli chcesz zmieniać n w trakcie działania, zawsze możesz utworzyć kopię i ją zmieniać, nie tracąc informacji o pierwotnej wartości parametru - wydaje mi się właśnie że to już kwestia raczej ideologiczna.
kontrukcja jest dobra, const może być z obu stron typu. ;)


@Mongoloid: Podejrzewam, że masz rację. ( ͡° ͜ʖ ͡°)

wydaje mi się właśnie że to już kwestia raczej ideologiczna.


No właśnie. Co mnie, użytkownika utworzonej przez Ciebie funkcji, obchodzi ideologia jaką się kierowałeś przy jej implementowaniu? Po prostu nie potrzebuję tej informacji w deklaracji, że nie zmienisz w środku swojej kopii n. I naprawdę nie rozumiem
To znaczy, że jak w C++ przyjmiesz stałą referencję na obiekt klasy Foo (tak jak się to zazwyczaj robi), to nie możesz zmienić jego stanu, na przykład ustawić jakiegoś pola.


@CamelCase: Dodaj "\* możesz, ale zazwyczaj nie powinieneś" i będzie dobrze


Widziałem też więcej przypadków użycia tego niż tylko muteksy itp. zazwyczaj jeśli klasa ma swój własny stan + jakieś wewnętrzne mechanizmy/obiekty, które mogą się zmieniać bez zmiany tego obiektu. Prosty
@AferaZaAfera: Nie no, brudny hak się zawsze znajdzie. Jak w życiu - jak chcesz złamać kontrakt to go złamiesz. Musisz się tylko liczyć z konsekwencjami.

Widziałem też więcej przypadków użycia tego niż tylko muteksy itp. zazwyczaj jeśli klasa ma swój własny stan + jakieś wewnętrzne mechanizmy/obiekty, które mogą się zmieniać bez zmiany tego obiektu. Prosty przykład to jak sobie jakiś caching robisz -> metoda getSomething() zwraca Ci coś np. z bazy
@CamelCase: Ty tu wyskakujesz z kontraktem, o czym nic nie wspominałem, a tylko mówię, że się da ;). Logiczny stan obiektu może się nie zmienić, co nie oznacza, że któreś pole może ulec zmianie i w niczym to nie przeszkadza. Chyba że odwołujesz się do const_casta. To brzydki hack, ale pewnie są jakieś sytuacje, w których jest konieczny (inaczej byśmy go nie mieli).

To jest właśnie memoizacja. ( ͡° ͜