В чем разница между "::" "."и "->" в 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 71

8 ответов:

1.-> для доступа к переменным-членам и методам объекта через pointer для объекта

Foo *foo = new Foo();
foo->member_var = 10;
foo->member_func();

2.. для доступа к переменным-членам и методам объекта через object instance

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;
}

':: 'для статических членов.

-> для указателей на экземпляр класса

. для экземпляров класса

:: is для имен классов - например, при использовании статического члена

другие ответили на разные синтаксисы, но обратите внимание, когда вы делаете свой couts, вы используете только ->:

int main()
{
    Kwadrat* kwadrat = new Kwadrat(1,2,3);
    cout<<kwadrat->val1<<endl;
    cout<<kwadrat->val2<<endl;
    cout<<kwadrat->val3<<endl;
    return 0;
}