В чем разница между "::" "." и "->" в С++
Возможный дубликат:
Когда я использую точку, стрелку или двойную двоеточие для ссылки на членов класса на С++?
Я создал класс под названием Kwadrat, и у меня есть три внутренних поля внутри. Блок кода дает мне совет, что я могу попасть в поле объекта ::
, .
и ->
. Стрела - это только работа, но почему? Какая разница между этими тремя?
#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
1. ->
для доступа к объектным переменным-членам и методам с помощью pointer
в объект
Foo *foo = new Foo();
foo->member_var = 10;
foo->member_func();
2. .
для доступа к объектным переменным-членам и методам через объект instance
Foo foo;
foo.member_var = 10;
foo.member_func();
3. ::
для доступа к статическим переменным и методам a class/struct
или namespace
. Он также может использоваться для доступа к переменным и функциям из другой области (фактически, класс, структура, пространство имен являются областями в этом случае)
int some_val = Foo::static_var;
Foo::static_method();
int max_int = std::numeric_limits<int>::max();
Ответ 2
В С++ вы можете получить доступ к полям или методам, используя разные операторы, в зависимости от типа:
- ClassName:: FieldName: общедоступное статическое поле и методы класса
- ClassInstance.FieldName: доступ к общедоступному полю (или методу) через ссылку класса
- ClassPointer- > FieldName: доступ к общедоступному полю (или методу) разыменованию указателя класса
Обратите внимание, что:: должно использоваться с именем класса, а не с экземпляром класса, поскольку статические поля или методы являются общими для всех экземпляров класса.
class AClass{
public:
static int static_field;
int instance_field;
static void static_method();
void method();
};
тогда вы получите доступ к этому пути:
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();
Ответ 3
Положить очень простой ::
- это оператор определения области видимости, .
- это оператор доступа (я забыл, что такое фактическое имя?), а ->
- стрелка разыменования.
::
- Область применения функции. То есть, он позволяет компилятору узнать, в каком классе работает функция, и, следовательно, как ее называть. Если вы используете этот оператор для вызова функции, функция является функцией static
.
.
- Это позволяет получить доступ к функции-члену на уже созданном объекте. Например, Foo x; x.bar()
вызывает метод bar()
для экземпляра объекта x
, который имеет тип Foo
. Вы также можете использовать это для доступа к общедоступным переменным класса.
->
- По существу то же самое, что и .
, за исключением того, что это работает с типами указателей. По сути, он разыгрывает указатель, а не вызывает .
. Использование этого эквивалентно (*ptr).method()
Ответ 4
У вас есть указатель на объект. Поэтому вам нужно получить доступ к полю объекта, на который указывает указатель. Чтобы разыскать указатель, который вы используете *
, и для доступа к полю, вы используете .
, поэтому вы можете использовать:
cout << (*kwadrat).val1;
Обратите внимание, что скобки необходимы. Эта операция достаточно распространена, что давно (когда C был молод) они решили создать "стенографический" способ сделать это:
cout << kwadrat->val1;
Они определены как идентичные. Как вы можете видеть, ->
в основном просто объединяет *
и .
в одну операцию. Если вы имели дело непосредственно с объектом или ссылкой на объект, вы могли бы использовать .
без разыменования указателя сначала:
Kwadrat kwadrat2(2,3,4);
cout << kwadrat2.val1;
::
- оператор разрешения области. Он используется, когда вам нужно только квалифицировать имя, но вы вообще не имеете дело с отдельным объектом. Это было бы прежде всего для доступа к статическому элементу данных:
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.
В этом случае, поскольку x
является static
, он не связан ни с одним конкретным экземпляром something
. Фактически, он будет существовать, даже если ни один экземпляр этого типа объекта не был создан. В этом случае мы можем получить доступ к нему с помощью оператора разрешения области видимости:
something::x = 10;
std::cout << something::x;
Обратите внимание, однако, что он также разрешает доступ к статическому члену, как если бы он был членом определенного объекта:
something s;
s.x = 1;
По крайней мере, если память служит, в начале истории С++ это не было разрешено, но смысл недвусмыслен, поэтому они решили разрешить его.
Ответ 5
Три оператора имеют связанные, но разные значения, несмотря на вводящую в заблуждение ноту из среды IDE.
Оператор ::
известен как оператор разрешения области видимости и используется для перехода из пространства имен или класса в один из его членов.
Операторы .
и ->
предназначены для доступа к членам экземпляра объекта и вступают в игру только после создания экземпляра объекта. Вы используете .
, если у вас есть фактический объект (или ссылка на объект, объявленный с помощью &
в объявленном типе), и вы используете ->
, если у вас есть указатель на объект (объявленный с помощью *
в объявленном типе).
Объект this
всегда является указателем на текущий экземпляр, поэтому почему оператор ->
является единственным, который работает.
Примеры:
// 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;
}
Ответ 6
"::" - для статических членов.
Ответ 7
- > предназначен для указателей на экземпляр класса
. для экземпляров класса
:: для классов - например, при использовании статического члена
Ответ 8
Другие ответили на разные синтаксисы, но учтите, что когда вы делаете свой couts
, вы используете только ->
:
int main()
{
Kwadrat* kwadrat = new Kwadrat(1,2,3);
cout<<kwadrat->val1<<endl;
cout<<kwadrat->val2<<endl;
cout<<kwadrat->val3<<endl;
return 0;
}