En C ++, marcar una función miembro const
significa que puede llamarse en const
instancias. 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
/ const
respectivamente. 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 const
miembros 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 const
es diferente. (También puede sobrecargar al tener solo const
una 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 const
en 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 final
y const
harías:
class Bar {
public:
virtual void foo() const final;
};
(Se requiere el orden const
y final
aquí).
Anteriormente no había un equivalente directo de las const
funciones miembro, aunque hacer que las funciones no virtual
fueran 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 private
constructores 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)