В чем разница между "::" "."и "->" в C++ [дубликат]
Возможные Дубликаты:
когда я использую точку, стрелку или двоеточие для ссылки на члены класса В C++?
Я создал класс под названием Kwadrat и у меня есть три поля int внутри. Блок кода дает мне совет, что я могу попасть в поле объекта с помощью ::
,.
и ->
. Стрела-это та, которая только работает, но почему? Какая разница между этими тремя?
#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;
}
8 ответов:
1.
->
для доступа к переменным-членам и методам объекта черезpointer
для объектаFoo *foo = new Foo(); foo->member_var = 10; foo->member_func();
2.
.
для доступа к переменным-членам и методам объекта через objectinstance
Foo foo; foo.member_var = 10; foo.member_func();
3.
::
для доступа к статическим переменным и методамclass/struct
илиnamespace
. Он также может быть использован для доступа к переменным и функциям из другой области (на самом деле класс, структура, пространство имен являются областями в этом случае)int some_val = Foo::static_var; Foo::static_method(); int max_int = std::numeric_limits<int>::max();
В C++ вы можете получить доступ к полям или методам, используя различные операторы, в зависимости от его типа:
- Имя_класса::Имя_поля: класс public static field and methods
- 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();
очень просто
::
оператор определения.
оператор доступа (я забыл, что фактическое имя?), и->
- это стрелка разыменования.
::
- область действия функции. То есть, он позволяет компилятору узнать, в каком классе живет функция и, таким образом, как ее вызвать. Если вы используете этот оператор для вызова функции, функция
у вас есть указатель на объект. Следовательно, вам нужно получить доступ к полю объекта, на который указывает указатель. Для разыменования указателя вы используете
*
, и доступ к полю, вы используете.
, так что вы можете использовать:cout << (*kwadrat).val1;
обратите внимание, что скобки нужны. Эта операция достаточно распространена, что давно (когда был молод) они решили создать "стенография" способ сделать это:
cout << kwadrat->val1;
они определены как идентичные. Как вы можете смотрите, это
->
в основном просто сочетает в себе*
и.
в одну операцию. Если вы имели дело непосредственно с объектом или ссылкой на объект, вы могли бы использовать.
без разыменования указателя сначала:Kwadrat kwadrat2(2,3,4); cout << kwadrat2.val1;
The
::
является оператором разрешения области. Он используется, когда вам нужно только квалифицировать имя, но вы не имеете дело с отдельным объектом вообще. Это было бы в первую очередь для доступа к статическим данным участник: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;
по крайней мере, если память не изменяет, рано в истории C++ это не было разрешено, но смысл однозначен, поэтому они решили разрешить это.
три оператора имеют связанные, но разные значения, несмотря на вводящее в заблуждение Примечание от IDE.
The
::
оператор известен как оператор разрешения области действия, и он используется, чтобы получить из пространства имен или класса к одному из его членов.The
.
и->
операторы предназначены для доступа к членам экземпляра объекта и вступают в игру только после создания экземпляра объекта. Вы используете.
Если у вас есть реальный объект (или ссылка на объект, объявленный с помощью&
в объявленном типе), а вы используете->
Если у вас есть указатель на объект (объявленные с*
в объявленном типе).The
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; }