que - Cuál es la diferencia entre "::" "." Y "->" en c++
lenguaje c++ ejemplos (8)
-> es para punteros a una instancia de clase
. es para instancias de clase
:: es para nombres de clase, por ejemplo cuando se usa un miembro estático
Posible duplicado:
¿Cuándo uso un punto, una flecha o dos puntos para referirme a los miembros de una clase en C ++?
Creé la clase llamada Kwadrat y tengo tres campos int dentro. Los bloques de código me dan consejos de que puedo entrar al campo del objeto por ::
, .
y ->
. La flecha es la que solo funciona, pero ¿por qué? ¿Cuál es la diferencia entre esos tres?
#include <iostream>
using namespace std;
class Kwadrat{
public:
int val1, val2, val3;
Kwadrat(int val1, int val2, int val3)
{
this->val1 = val1;
//this.val2 = val2;
//this::val3 = val3;
}
};
int main()
{
Kwadrat* kwadrat = new Kwadrat(1,2,3);
cout<<kwadrat->val1<<endl;
cout<<kwadrat->val2<<endl;
cout<<kwadrat->val3<<endl;
return 0;
}
1. ->
para acceder a las variables y métodos de los miembros del objeto a través del pointer
al objeto
Foo *foo = new Foo();
foo->member_var = 10;
foo->member_func();
2 .
para acceder a las variables y métodos de los miembros del objeto a través de una instance
objeto
Foo foo;
foo.member_var = 10;
foo.member_func();
3. ::
para acceder a variables estáticas y métodos de una class/struct
o namespace
. También se puede usar para acceder a variables y funciones desde otro ámbito (en realidad, clase, estructura, espacio de nombres son ámbitos en ese caso)
int some_val = Foo::static_var;
Foo::static_method();
int max_int = std::numeric_limits<int>::max();
El ''::'' es para miembros estáticos.
En C ++ puede acceder a campos o métodos, usando diferentes operadores, dependiendo de su tipo:
- ClassName :: FieldName : class public static field and methods
- ClassInstance.FieldName : acceder a un campo público (o método) a través de la referencia de clase
- ClassPointer-> FieldName : acceder a un campo público (o método) desreferenciando un puntero de clase
Tenga en cuenta que :: se debe usar con un nombre de clase en lugar de una instancia de clase, ya que los campos o métodos estáticos son comunes a todas las instancias de una clase.
class AClass{
public:
static int static_field;
int instance_field;
static void static_method();
void method();
};
entonces accedes de esta manera:
AClass instance;
AClass *pointer = new AClass();
instance.instance_field; //access instance_field through a reference to AClass
instance.method();
pointer->instance_field; //access instance_field through a pointer to AClass
pointer->method();
AClass::static_field;
AClass::static_method();
Los tres operadores tienen significados relacionados pero diferentes, a pesar de la nota engañosa del IDE.
El operador ::
se conoce como el operador de resolución de alcance , y se usa para pasar de un espacio de nombres o clase a uno de sus miembros.
El .
y ->
operadores son para acceder a los miembros de una instancia de objeto, y solo entran en juego después de crear una instancia de objeto. Tu usas si tiene un objeto real (o una referencia al objeto, declarado con &
en el tipo declarado), y usa ->
si tiene un puntero a un objeto (declarado con *
en el tipo declarado).
this
objeto siempre es un puntero a la instancia actual, por lo que el operador ->
es el único que funciona.
Ejemplos:
// In a header file
namespace Namespace {
class Class {
private:
int x;
public:
Class() : x(4) {}
void incrementX();
};
}
// In an implementation file
namespace Namespace {
void Class::incrementX() { // Using scope resolution to get to the class member when we aren''t using an instance
++(this->x); // this is a pointer, so using ->. Equivalent to ++((*this).x)
}
}
// In a separate file lies your main method
int main() {
Namespace::Class myInstance; // instantiates an instance. Note the scope resolution
Namespace::Class *myPointer = new Namespace::Class;
myInstance.incrementX(); // Calling a function on an object instance.
myPointer->incrementX(); // Calling a function on an object pointer.
(*myPointer).incrementX(); // Calling a function on an object pointer by dereferencing first
return 0;
}
Otros han respondido las diferentes sintaxis, pero tenga en cuenta que cuando está haciendo couts
, solo está usando ->
:
int main()
{
Kwadrat* kwadrat = new Kwadrat(1,2,3);
cout<<kwadrat->val1<<endl;
cout<<kwadrat->val2<<endl;
cout<<kwadrat->val3<<endl;
return 0;
}
Ponga muy simple ::
es el operador de scoping,. es el operador de acceso (¿Olvidé el nombre real?), y ->
es la flecha de referencia.
::
- Alcance una función. Es decir, le permite al compilador saber en qué clase vive la función y, por lo tanto, cómo llamarla. Si está utilizando este operador para llamar a una función, la función es static
.
.
- Esto permite el acceso a una función miembro en un objeto ya creado. Por ejemplo, Foo x; x.bar()
Foo x; x.bar()
llama al método bar()
en el objeto instanciado x
que tiene el tipo Foo
. También puede usar esto para acceder a las variables de clase pública.
->
- Esencialmente lo mismo que .
excepto que esto funciona en tipos de punteros. En esencia, desreferencia el puntero, que las llamadas .
. Usar esto es equivalente a (*ptr).method()
Usted tiene un puntero a un objeto. Por lo tanto, debe acceder a un campo de un objeto apuntado por el puntero. Para eliminar la referencia del puntero que usa *
, y para acceder a un campo, lo usa .
, entonces puedes usar:
cout << (*kwadrat).val1;
Tenga en cuenta que los paréntesis son necesarios. Esta operación es bastante común que hace mucho tiempo (cuando C era joven) decidieron crear un método de "taquigrafía" para hacerlo:
cout << kwadrat->val1;
Estos se definen para ser idénticos. Como puede ver, el ->
básicamente solo combina un *
y un .
en una sola operación. Si estuviera tratando directamente con un objeto o una referencia a un objeto, podría usar el .
sin desreferenciar un puntero primero:
Kwadrat kwadrat2(2,3,4);
cout << kwadrat2.val1;
The ::
es el operador de resolución de alcance. Se usa cuando solo necesita calificar el nombre , pero no se trata de un objeto individual en absoluto. Esto sería principalmente para acceder a un miembro de datos estáticos:
struct something {
static int x; // this only declares `something::x`. Often found in a header
};
int something::x; // this defines `something::x`. Usually in .cpp/.cc/.C file.
En este caso, dado que x
es static
, no está asociado a ninguna instancia particular de something
. De hecho, existirá incluso si no se ha creado ninguna instancia de ese tipo de objeto. En este caso, podemos acceder a él con el operador de resolución de alcance:
something::x = 10;
std::cout << something::x;
Tenga en cuenta, sin embargo, que también se le permite acceder a un miembro estático como si fuera miembro de un objeto particular:
something s;
s.x = 1;
Al menos si la memoria sirve, al principio de la historia de C ++ esto no estaba permitido, pero el significado es inequívoco, por lo que decidieron permitirlo.