В чем разница между "::" "."и "->" в 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.
.для доступа к переменным-членам и методам объекта через objectinstanceFoo 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; }