Подтвердить что ты не робот

В чем разница между "::" "." и "->" в С++

Возможный дубликат:
Когда я использую точку, стрелку или двойную двоеточие для ссылки на членов класса на С++?

Я создал класс под названием 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;
}
4b9b3361

Ответ 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;
}