En C ++, marcar una función miembro constsignifica que puede llamarse en constinstancias. Java no tiene un equivalente a esto. P.ej:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Los valores se pueden asignar, una vez, más tarde en Java solo, por ejemplo:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
es legal en Java, pero no en C ++ mientras 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.
}
}
Tanto en Java como en C ++, las variables miembro pueden ser final/ constrespectivamente. Es necesario darles un valor para cuando se termine de construir una instancia de la clase.
En Java se deben configurar antes de que el constructor haya terminado, esto se puede lograr de una de dos maneras:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
En C ++ necesitará usar listas de inicialización para dar a los constmiembros un valor:
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
En Java final se puede usar para marcar cosas como no reemplazables. C ++ (pre-C ++ 11) no hace esto. P.ej:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Pero en C ++:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
Esto está bien, porque la semántica de marcar una función miembro constes diferente. (También puede sobrecargar al tener solo constuna de las funciones miembro. (Tenga en cuenta también que C ++ 11 permite que las funciones miembro se marquen como finales, consulte la sección de actualización de C ++ 11)
Actualización de C ++ 11:
De hecho, C ++ 11 le permite marcar tanto las clases como las funciones miembro como final, con semántica idéntica a la misma característica en Java, por ejemplo en Java:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Ahora se puede escribir exactamente en C ++ 11 como:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
Tuve que compilar este ejemplo con un prelanzamiento de G ++ 4.7. Tenga en cuenta que esto no reemplaza consten este caso, sino que lo aumenta, proporcionando el comportamiento similar a Java que no se vio con la palabra clave C ++ equivalente más cercana. Entonces, si quisieras que una función miembro fuera ambas finaly constharías:
class Bar {
public:
virtual void foo() const final;
};
(Se requiere el orden consty finalaquí).
Anteriormente no había un equivalente directo de las constfunciones miembro, aunque hacer que las funciones no virtualfueran una opción potencial, aunque sin causar un error en el momento de la compilación.
Asimismo el Java:
public final class Bar {
}
public class Error extends Bar {
}
se convierte en C ++ 11:
class Bar final {
};
class Error : public Bar {
};
(Anteriormente, los privateconstructores eran probablemente lo más cercano a esto en C ++)
Curiosamente, para mantener la compatibilidad con el código anterior a C ++ 11 final no es una palabra clave de la manera habitual. (Tome el ejemplo trivial y legal de C ++ 98 struct final;para ver por qué convertirlo en una palabra clave rompería el código)