En C ++, le marquage d'une fonction membre const
signifie qu'elle peut être appelée sur des const
instances. Java n'a pas d'équivalent à cela. Par exemple:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Les valeurs peuvent être attribuées, une fois, plus tard uniquement en Java, par exemple:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
est légal en Java, mais pas en C ++ alors que:
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
Dans les deux variables membres Java et C ++ peuvent être final
/ const
respectivement. Il faut leur donner une valeur au moment où une instance de la classe est terminée en cours de construction.
En Java, ils doivent être définis avant que le constructeur ait terminé, cela peut être réalisé de deux manières:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
En C ++, vous devrez utiliser des listes d'initialisation pour donner const
une valeur aux membres:
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 non remplaçables. C ++ (pré-C ++ 11) ne le fait pas. Par exemple:
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 {
}
};
c'est bien, car la sémantique du marquage d'une fonction membre const
est différente. (Vous pouvez également surcharger en ne disposant que de l' const
une des fonctions membres. (Notez également que C ++ 11 permet aux fonctions membres d'être marquées comme finales, voir la section mise à jour C ++ 11)
Mise à jour C ++ 11:
C ++ 11 vous permet en fait de marquer à la fois les classes et les fonctions membres comme final
, avec une sémantique identique à la même fonctionnalité 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 écrit exactement en C ++ 11 comme:
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 cela ne remplace pas const
dans ce cas, mais plutôt l'augmente, fournissant le comportement de type Java qui n'a pas été vu avec le mot clé C ++ équivalent le plus proche. Donc, si vous vouliez qu'une fonction membre soit à la fois final
etconst
vous feriez:
class Bar {
public:
virtual void foo() const final;
};
(L'ordre de const
et final
ici est obligatoire).
Auparavant, il n'y avait pas d'équivalent direct de const
fonctions membres, bien que rendre les fonctions non - virtual
serait une option potentielle bien que sans causer d'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 étaient probablement les plus proches que vous pouviez obtenir en C ++)
Fait intéressant, afin de maintenir la compatibilité ascendante avec le code pré-C ++ 11, ce final
n'est pas un mot clé de la manière habituelle. (Prenons l'exemple trivial et légal du C ++ 98 struct final;
pour voir pourquoi en faire un mot clé casserait le code)