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?

Author: WinWin, 2011-02-11

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 jako final, 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)

 202
Author: Flexo,
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.

 31
Author: Ralph,
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
 29
Author: BlueRaja - Danny Pflughoeft,
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();
 13
Author: James Schek,
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++

 8
Author: pocketdora,
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.

 8
Author: josefx,
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.

 3
Author: antak,
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.
 2
Author: KevenK,
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.

 2
Author: Dima,
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
 1
Author: Subbu Mahadev,
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.

 -7
Author: HungNM2,
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