C++ 中的 "::" "." 和 "->" 有什么区别

What is the difference between "::" "." and "->" in c++

本文关键字:什么 gt 区别 中的 C++      更新时间:2023-10-16

我创建了一个名为Kwadrat的类。该类有三个int字段。我的开发环境建议我通过 :: & -> 运算符访问Kwadrat创建对象的字段。我尝试了这两个运算符,发现->运算符能够成功访问对象字段中的数据,尽管对于->运算符来说并非如此。我还发现.运算符也将访问类成员。我很困惑,不明白为什么有三个成员用于访问对象成员和/或方法。有人可以向我解释一下这三个运算符之间的区别吗?

<小时 />

1. ->

2. ::

3. .

<小时 />

    #include <iostream>
    using namespace std;
    class Kwadrat{
    public: 
        int val1,
            val2,
            val3;
        Kwadrat(int val1, int val2, int val3)
        {
            this->val1 = val1; // Working
            this.val2 = val2;  // Doesn't Work!
            this::val3 = val3; // Doesn't Work!
        }
    };

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

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. ::用于访问class/structnamespace的静态变量和方法。它还可用于从另一个作用域访问变量和函数(在这种情况下,类、结构、命名空间实际上是作用域)

int some_val = Foo::static_var;
Foo::static_method();
int max_int = std::numeric_limits<int>::max();

在C++中,您可以使用不同的运算符访问字段或方法,具体取决于其类型:

    类名::字段
  • 名:类公共静态字段和方法
  • ClassInstance.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();

很简单::是范围运算符,.是访问运算符(我忘记了实际名称是什么?),->是取消引用箭头。

:: - 限定函数的范围。也就是说,它让编译器知道函数位于哪个类中,从而知道如何调用它。如果使用此运算符调用函数,则该函数是static函数。

. - 这允许访问已创建对象上的成员函数。例如,Foo x; x.bar()调用方法bar() 在类型为 Foo 的实例化对象x。您还可以使用它来访问公共类变量。

-> - 本质上与.相同,只是这适用于指针类型。本质上,它取消引用指针,而不是调用.。使用它等效于(*ptr).method()

您有一个指向对象的指针。因此,您需要访问指针指向的对象字段。要取消引用您使用的指针* 并访问字段,请使用 . ,因此可以使用:

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.

在这种情况下,由于xstatic,因此它不与something的任何特定实例相关联。事实上,即使没有创建该类型对象的实例,它也会存在。在这种情况下,我们可以使用范围解析运算符访问它:

something::x = 10;
std::cout << something::x;

但请注意,它也允许访问静态成员,就好像它是特定对象的成员一样:

something s;
s.x = 1;

至少如果没记错的话,在C++历史的早期,这是不允许的,但意思是明确的,所以他们决定允许它。

这三个

运算符具有相关但不同的含义,尽管 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;
}

-> 表示指向类实例的指针

. 用于类实例

:: 用于类名 - 例如,使用静态成员时

'::' 用于静态成员。

其他人已经回答了不同的语法,但请注意,当你做你的couts时,你只使用->

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