一个非常常见的混淆来源是认为 Java 和 C++ 中的引用是相似的,因为它们具有相同的名称。这无疑是错误的。
考虑一个名为 Dog 的 C++ 或 Java 类,其构造函数支持 name 以及 getName 和 setName 方法。
在 Java 中,这个使用引用的代码是有效的:
Perro perroA = new Perro("Gordito");
// Puedes cambiar la referencia contenida en perroA
perroA = new Perro("Gruñon");
Perro perroB; // Puedes declarar una variable de tipo referencia
// sin inicializarla explícitamente.
perroB = new Perro("Comilon"); // Y luego asignarle un objeto
perroB = perroA; // Ahora perroA y perroB referencian el mismo objeto
perroA.asignaNombre("Fifi"); // Modifica tanto perroA como perroB
System.out.println(perroB.obtenerNombre()); // Imprimie "Fifi"
C++ 中使用引用的相同代码无法编译,并且当它编译时(删除标有 的行!!!),它的作用与 Java 不同:
Perro perroObj1("Gordito");
Perro perroObj2("Comilon");
Perro& perroA = perroObj1; // Correcto
// No puedes cambiar el objeto al que referencia
// una variable tipo referencia en C++
perroA = Perro("Gruñon"); // Compila, pero no hace lo mismo que en Java
// perroA sique referenciando al mismo objeto, no a otro como en Java
// Lo que sucede en C++ es que se invoca el operador de asignación.
Perro& perroB; // !!!Error compilacion. No puedes declarar variables
// referencia sin inicializarlas.
perroB = perroObj2; // !!! Demasiado tarde
Perro& perroB = perroObj2; // Correcto
perroB = perroA; // No hace lo mismo que en java
perroA.asignaNombre("Fifi"); // Modificamos perroA pero no perroB
std::cout << perroB.obtenerNombre() << std::endl; // Imprimie "Gruñon", no "Fifi"
带有指针的 C++ 中的相同代码将是有效的,并且与 java 中的代码相同。
Perro* perroA = new Perro("Gordito");
// Puedes cambiar el puntero contenido en perroA
perroA = new Perro("Gruñon");
Perro* perroB; // Puedes declarar una variable de tipo puntero
// sin inicializarla explícitamente.
perroB = new Perro("Comilon"); // Y luego asignarle un puntero a objeto
perroB = perroA; // Ahora perroA y perroB apuntan al mismo objeto
perroA->asignaNombre( "Fifi" ); // Modifica tanto perroA como perroB
std::cout << perroB->obtenerNombre() << std::endl; // Imprime "Fifi"
在参数传递方面,Java 引用也与 C++ 引用有很大不同。
public static void main(String[] args)
{
Perro unPerro = new Perro("Tim");
cambiarNombre( unPerro );
}
public static void cambiarNombre(Perro p) {
p = new Perro("Fifi"); // No modifica unPerro en main
}
C++ 引用也不会使 aDog 引用另一个对象,但与 Java 不同的是,它确实会根据赋值运算符的工作方式更改unPerroen的内容main(假设赋值运算符的正常实现):
int main(void)
{
Perro unPerro("Tim");
cambiarNombre( unPerro );
return 0;
}
void cambiarNombre(Perro& d) {
d = Perro("Fifi"); // Sí modifica unPerro en main
// a través del operador de asignación
}
在 C++ 中通过指针传递参数的情况下,它与在 Java 中具有相同的效果,因为 C++ 中的指针也是按值传递的,就像 Java 引用一样:
int main(void)
{
Perro* unPerro = new Perro("Tim");
cambiarNombre( unPerro );
return 0;
}
void cambiarNombre(Perro* d) {
// Como en Java, no tiene efecto sobre la variable unPerro en main
d = new Perro("Fifi");
}
到目前为止,Java 引用看起来很像 C++ 指针,并且与 C++ 引用非常不同。
但是 C++ 中的指针和 Java 中的引用之间也有重要的区别:
Gato gato = new Gato("Minino");
System.out.println(gato.getNombre()); // Minino
cambiarGato(gato);
public void cambiarGato(Gato gato) { // dirección de gato
gato.setNombre("Michifu");
gato = new Gato("Firulais"); // se reasigna una nueva dirección y se pierde la dirección original
}
System.out.println(gato.getNombre()); // Michifu
对于高级 C++ 程序员来说,解释 java 或 java 的一部分的最好方法是说:
一个非常常见的混淆来源是认为 Java 和 C++ 中的引用是相似的,因为它们具有相同的名称。这无疑是错误的。
考虑一个名为 Dog 的 C++ 或 Java 类,其构造函数支持 name 以及 getName 和 setName 方法。
在 Java 中,这个使用引用的代码是有效的:
C++ 中使用引用的相同代码无法编译,并且当它编译时(删除标有 的行
!!!
),它的作用与 Java 不同:带有指针的 C++ 中的相同代码将是有效的,并且与 java 中的代码相同。
在参数传递方面,Java 引用也与 C++ 引用有很大不同。
C++ 引用也不会使 aDog 引用另一个对象,但与 Java 不同的是,它确实会根据赋值运算符的工作方式更改
unPerro
en的内容main
(假设赋值运算符的正常实现):在 C++ 中通过指针传递参数的情况下,它与在 Java 中具有相同的效果,因为 C++ 中的指针也是按值传递的,就像 Java 引用一样:
到目前为止,Java 引用看起来很像 C++ 指针,并且与 C++ 引用非常不同。
但是 C++ 中的指针和 Java 中的引用之间也有重要的区别:
delete
因此不会发生。不用多说,在 Java 中一切都是按值传递的。对象似乎是通过引用传递的原因是因为实际上,当您将对象作为参数传递时,您实际上是在传递它指向的内存中地址的值,这就是您可以更改对象属性的原因通过它的地址,但是如果您尝试重新实例化,该地址将丢失并且将分配一个新地址(来自最近的实例化)。