FINAL Java vs const C++
The Java for C++ programmers tutorial says that (highlight is my own):
Słowo kluczowe final to mniej więcej odpowiednik const w C++
Co w tym kontekście oznacza "z grubsza"? Czy nie są one dokładnie takie same?
Jakie są różnice, jeśli w ogóle?
11 answers
W C++ oznaczenie funkcji członka const
oznacza, że może być wywoływana na instancjach const
. Java nie ma takiego odpowiednika. Np.:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Wartości można przypisać, raz, później tylko w Javie np.:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
[[30]}jest legalne w Javie, ale nie w C++ natomiast:
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
Zarówno w Javie jak i C++ zmienne członkowskie mogą być final
/const
odpowiednio. Muszą one otrzymać wartość do czasu zakończenia budowy instancji klasy.
W Java muszą być ustawione przed zakończeniem konstruktora, można to osiągnąć na jeden z dwóch sposobów:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
W C++ musisz użyć listy inicjalizacyjnej, aby nadać const
członkom wartość:
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
W Javie final może być używany do oznaczania rzeczy jako nie nadpisywalne. C++ (pre-C++11) tego nie robi. Np.:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Ale w C++:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
Jest to w porządku, ponieważ semantyka oznaczania funkcji członowej const
jest inna. (Można też przeciążenie przez posiadanie tylko {[12] } na jednej z funkcji Członkowskich. (Zauważ również, że C++11 pozwala na oznaczanie funkcji składowych jako końcowych, zobacz sekcję C++11 update)
C++11 update:
C++11 w rzeczywistości pozwala na oznaczanie zarówno klas, jak i funkcji składowych jakofinal
, z identyczną semantyką do tej samej funkcji w Javie, na przykład w Javie:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Może być teraz dokładnie napisane w C++11 jako:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
Musiałem skompilować ten przykład z pre-release G++ 4.7. Zauważ, że to nie zastępuje const
w tym przypadku, ale raczej ją rozszerza, zapewniając zachowanie podobne do Javy, które nie było widoczne przy najbliższym odpowiedniku słowa kluczowego C++. Jeśli więc chcesz, aby funkcja member była zarówno final
, jak i const
, wykonałbyś:
class Bar {
public:
virtual void foo() const final;
};
(kolejność const
i final
tutaj jest wymagana).
Wcześniej nie było bezpośredniego odpowiednika const
funkcji Członkowskich, chociaż tworzenie funkcji Nie-virtual
byłoby potencjalną opcją, chociaż bez powodowania błędu podczas kompilacji.
Podobnie Java:
public final class Bar {
}
public class Error extends Bar {
}
Staje się w C++11:
class Bar final {
};
class Error : public Bar {
};
Constructors był prawdopodobnie najbardziej zbliżony do tego w C++.]}
Co ciekawe, w celu zachowania wstecznej kompatybilności z kodem pre-C++11final
nie jest słowem kluczowym w zwykły sposób. (Weźmy trywialny, legalny przykład C++98 struct final;
, aby zobaczyć, dlaczego uczynienie go słowem kluczowym łamie kod)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-30 16:34:26
W Javie ostatnie słowo kluczowe może być użyte do czterech rzeczy:
- Na klasie lub metodzie, aby ją uszczelnić (bez podklas / nadpisywania dozwolone)
- na zmiennej member, aby zadeklarować, że jest może być ustawiona dokładnie raz (myślę, że o tym mówisz)
- na zmiennej zadeklarowanej w metodzie, aby upewnić się, że można ją ustawić dokładnie raz
- na parametrze metody, aby zadeklarować, że nie można go modyfikować w ramach metody
Jedną ważną rzeczą jest: A Java final member variable must be set exactly one! Na przykład w konstruktorze, deklaracji pola lub inicjalizatorze. (Ale nie można ustawić końcowej zmiennej członkowskiej w metodzie).
Kolejna konsekwencja uczynienia zmiennej członkowskiej ostateczną odnosi się do modelu pamięci, co jest ważne, jeśli pracujesz w środowisku wątkowym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-03 22:00:27
A const
obiekt może wywoływać tylko metody const
i jest ogólnie uważany za niezmienny.
const Person* person = myself;
person = otherPerson; //Valid... unless we declared it const Person* const!
person->setAge(20); //Invalid, assuming setAge isn't a const method (it shouldn't be)
Obiektu final
nie można ustawić na nowy obiekt, ale nie jest on niezmienny - nic nie powstrzyma kogoś przed wywołaniem jakichkolwiek metod set
.
final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!
Java nie ma nieodłącznego sposobu deklarowania obiektów niezmiennych; musisz zaprojektować klasę jako niezmienną.
Gdy zmienna jest typem prymitywnym, final
/const
pracuj tak samo.
const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-12 16:55:28
Java final jest odpowiednikiem C++ const na prymitywnych typach wartości.
W typach odwołań Java, ostateczne słowo kluczowe jest równoważne wskaźnikowi const... tj.
//java
final int finalInt = 5;
final MyObject finalReference = new MyObject();
//C++
const int constInt = 5;
MyObject * const constPointer = new MyObject();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-11 16:14:51
Masz tu już kilka świetnych odpowiedzi, ale jeden punkt, który wydawał się wart dodania: const
W C++ jest powszechnie używany, aby zapobiec zmianie stanu obiektów przez inne części programu. Jak już wspomniano, final
w Javie nie może tego zrobić (z wyjątkiem primitives) - po prostu uniemożliwia zmianę referencji na inny obiekt. Ale jeśli używasz Collection
, możesz zapobiec zmianom w swoich obiektach za pomocą metody statycznej
Collection.unmodifiableCollection( myCollection )
To zwraca Collection
odniesienie to daje dostęp do odczytu elementów, ale rzuca wyjątek, jeśli modyfikacje są próbowane, co czyni go trochę jak const
w C++
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-13 16:25:39
final
Java działa tylko na typach prymitywnych i referencjach, nigdy na samych obiektach, w których słowo kluczowe const działa na czegokolwiek.
Porównaj const list<int> melist;
z final List<Integer> melist;
pierwszy uniemożliwia modyfikację listy, a drugi uniemożliwia przypisanie nowej Listy Do melist
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-12 07:44:34
Oprócz pewnych i subtelnych właściwości wielowątkowych , zmienne deklarowane final
nie musisz być inicjowany na Deklaracji!
Czyli jest to ważne w Javie:
// declare the variable
final int foo;
{
// do something...
// and then initialize the variable
foo = ...;
}
To nie byłoby poprawne, gdyby zostało napisane w C++'s const
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-30 02:12:37
Według Wikipedii :
- W C++ pole const jest nie tylko chronione przed ponownym przypisaniem, ale istnieje dodatkowe ograniczenie, że tylko metody const mogą być wywoływane na nim i mogą być przekazywane tylko jako argument const innych metod.
- Niestatyczne klasy wewnętrzne mogą swobodnie uzyskać dostęp do dowolnego pola klasy zamkniętej, końcowego lub nie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-11 16:12:15
Zgaduję, że jest napisane "z grubsza", ponieważ znaczenie const
W C++ komplikuje się, gdy mówimy o wskaźnikach, tj. wskaźnikach stałych vs wskaźnikach do stałych obiektów. Ponieważ w Javie nie ma "jawnych" wskaźników, final
nie ma tych problemów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-11 16:12:16
Wyjaśnię to, co zrozumiałem na przykładzie instrukcji switch/case.
Wartości w każdym przypadku muszą być wartościami stałymi w czasie kompilacji tego samego typu danych co wartość przełącznika.
Zadeklaruj coś takiego jak poniżej (albo w Twojej metodzie jako lokalne instancje, albo w twojej klasie jako zmienną statyczną (Dodaj do niej wtedy statyczną), albo zmienną instancyjną.
final String color1 = "Red";
I
static final String color2 = "Green";
switch (myColor) { // myColor is of data type String
case color1:
//do something here with Red
break;
case color2:
//do something with Green
break;
}
Ten kod nie będzie kompilowany, jeśli color1
jest zmienną klasy / instancji, a nie lokalną zmienna.
Zostanie skompilowana, jeśli {[3] } zostanie zdefiniowana jako static final (wtedy stanie się static final variable).
Gdy nie zostanie skompilowana, pojawi się następujący błąd
error: constant string expression required
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-18 10:34:54
Słowo kluczowe "const" oznacza, że zmienna jest zapisana w pamięci ROM (z mikroprocesorem). w komputerze zmienna jest zapisywana w obszarze RAM dla kodu złożenia(tylko do odczytu RAM). oznacza to, że Twoja zmienna nie znajduje się w zapisywalnej pamięci RAM obejmującej: pamięć statyczną, pamięć stosu i pamięć sterty.
Słowo kluczowe "final" oznacza, że zmienna jest zapisywana w pamięci RAM, ale kompilator zwraca uwagę, że zmienna zmienia się tylko jeden raz.
//in java language you can use:
static final int i =10;
i =11; //error is showed here by compiler
//the same in C++ the same as follows
int i =10;
const int &iFinal = i;
iFinal = 11; //error is showed here by compiler the same as above
Myślę, że "const" jest zły w wydajności, więc Java go nie używa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-18 17:36:30