162 votes

Java ' s final vs C++ ' s const

Le Java pour le tutoriel de programmeurs C++ dit que (point culminant est mon propre) :

Le mot clé final est à peu près équivalent à const en C++

Que signifie « grosso modo » dans ce contexte ? Ne sont-ils pas exactement la même chose ?

Quelles sont les différences, le cas échéant ?

207voto

Flexo Points 39273

En C++ marquage d'une fonction membre const signifie qu'il peut être appelé sur const des cas. Java n'a pas d'équivalent à ce. E. g.:

class Foo {
public:
   void bar();
   void foo() const;
};

void test(const Foo& i) {
   i.foo(); //fine
   i.bar(); //error
}

Les valeurs peuvent être affectées à une, plus tard, en Java, par exemple:

public class Foo {
   void bar() {
     final int a;
     a = 10;
   }
}

est légal en Java, mais pas du C++ alors que:

public class Foo {
   void bar() {
     final int a;
     a = 10;
     a = 11; // Not legal, a has already been assigned a value.
   }
}

En Java et en C++ variables de membre peuvent être final/const respectivement. Ces le besoin d'être donné une valeur à la fois une instance de la classe est fini d'être construit.

En Java, ils doivent être définis avant que le constructeur a terminé, il peut être atteint de deux façons:

public class Foo {
   private final int a;
   private final int b = 11;
   public Foo() {
      a = 10;
   }
}

En C++, vous aurez besoin d'utiliser l'initialisation des listes de donner des const des membres d'une valeur:

class Foo {
   const int a;
public:
   Foo() : a(10) {
      // Assignment here with = would not be legal
   }
};

En Java final peut être utilisé pour marquer des choses comme des non-substituables. C++ (avant C++11) ne pas faire cela. E. g.:

public class Bar {
   public final void foo() {
   }
}

public class Error extends Bar {
   // Error in java, can't override
   public void foo() {
   }
}

Mais en C++:

class Bar {
public:
   virtual void foo() const {
   }
};

class Error: public Bar {
public:
   // Fine in C++
   virtual void foo() const {
   }
};

ce qui est bien, parce que la sémantique de marquage d'une fonction membre const sont différentes. (Vous pouvez aussi la surcharge en ayant seulement l' const sur l'une des fonctions membres. (Note également que le C++11 permet des fonctions de membre pour être marqué en finale, voir le C++11 mise à jour de l'article)


C++11 mise à jour:

C++11 dans les faits, vous permettent de marquer les deux classes et fonctions de membre en tant que final, à l'identique de la sémantique de la même fonction en Java, par exemple en Java:

public class Bar {
   public final void foo() {
   }
}

public class Error extends Bar {
   // Error in java, can't override
   public void foo() {
   }
}

Peut maintenant être exactement écrit en C++11:

class Bar {
public:
  virtual void foo() final;
};

class Error : public Bar {
public:
  virtual void foo() final;
};

J'ai dû compiler cet exemple, avec une pré-version de G++ 4.7. Notez que ceci ne remplace pas l' const dans ce cas, mais plutôt il augmente, en fournissant le Java comme un comportement qui n'a pas été vu avec l'équivalent le plus proche de C++ mot-clé. Donc si vous voulez une fonction membre pour être à la fois final et const vous ne:

class Bar {
public:
  virtual void foo() const final;
};

(L'ordre de const et final ici est requis).

Auparavant il n'y avait pas d'équivalent direct de l' const fonctions de membre de bien que les fonctions non-virtual serait une option mais sans provoquer une erreur au moment de la compilation.

De même, le Java:

public final class Bar {
}

public class Error extends Bar {
}

devient en C++11:

class Bar final {
};

class Error : public Bar {
};

(Précédemment private constructeurs était probablement le plus proche, vous pouvez arriver à cela en C++)

Il est intéressant de noter, dans le but de maintenir la compatibilité avec des pré-C++11 code final n'est pas un mot clé dans la manière habituelle. (Prendre le trivial, juridique C++98 exemple struct final; de voir pourquoi en faire un mot-clé serait le code de saut)

37voto

Un const objet ne peut appeler const méthodes, et est généralement considéré comme immuable.

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)

Un final objet ne peut pas être fixé à un nouvel objet, mais il n'est pas immuable -, rien n'empêche quelqu'un d'appeler des set méthodes.

final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!

Java n'a pas inhérente façon de déclarer des objets immuables; vous avez besoin pour la conception de la classe comme immuables vous-même.

Lorsque la variable est d'un type primitif, final/const fonctionner de la même.

const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages

31voto

Ralph Points 42744

En Java, le mot-clé final peut être utilisé pour quatre choses:

  • sur une classe ou une méthode pour le fermer (pas de sous-classes / prépondérant autorisé)
  • sur une variable membre à déclarer que c'est peut être définie exactement une fois (je pense que c'est ce dont vous parlez)
  • sur une variable déclarée dans une méthode, assurez-vous qu'il peut être mis exactement une fois
  • sur un paramètre d'une méthode, de déclarer qu'il ne peut pas être modifiée dans la méthode

Une chose importante est: Java dernier membre de la variable doit être définie exactement une fois! Par exemple, dans un constructeur, le champ de la déclaration, ou intializer. (Mais vous ne pouvez pas définir une dernière variable de membre dans une méthode).

Une autre conséquence de rendre une variable de membre de finale se rapporte à la mémoire de modèle, ce qui est important si vous travaillez dans une tige filetée de l'environnement.

14voto

James Schek Points 11070

Java final équivaut à C++ const sur les types valeur primitifs.

Types de Java de référence, le mot clé final est équivalent à un pointeur const... c'est-à-dire

9voto

josefx Points 8417

Javas finales fonctionne uniquement sur les types primitifs et références, jamais sur les instances d’objets eux-mêmes où le mot clé const fonctionne sur n’importe quoi.

Comparer avec le premier, il est impossible de modifier la liste, tandis que le plus tard seul ne vous empêche d’assignation d’une nouvelle liste à melist.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X