在c ++中“::”“。”和“ – >”有什么区别?

可能重复:
什么时候使用点,箭头或双冒号引用C ++中的类的成员?

我创build了一个叫Kwadrat的类,里面有三个int字段。 代码块给了我build议,我可以通过:: ,进入对象的领域.-> 。 箭是唯一的工作,但为什么? 这三者有什么区别?

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

1. ->通过pointer对象的pointer访问对象成员variables和方法

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

2 . 用于通过对象instance访问对象成员variables和方法

 Foo foo; foo.member_var = 10; foo.member_func(); 

3. ::用于访问class/structnamespace静态variables和方法。 它也可以用来访问另一个范围的variables和函数(实际上类,结构体,命名空间是这种情况下的范围)

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

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

  • ClassName :: FieldName :类public static field和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(); 

把非常简单::是范围操作符, . 是访问操作符(我忘记了实际的名字是什么?), ->是取消引用箭头。

:: – 范围一个函数。 也就是说,它让编译器知道该函数所在的类是什么,因此如何调用它。 如果您正在使用此运算符来调用函数,则该函数是一个static函数。

. – 这允许访问已经创build的对象上的成员函数。 例如, Foo x; x.bar() Foo x; x.bar()调用具有typesFoo实例化对象x上的方法bar() 。 你也可以用它来访问公共类variables。

-> – 基本上是一样的事情. 除了这个指针types。 实质上,它将指针解除引用,而不是调用. 。 使用这个相当于(*ptr).method()

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

 cout << (*kwadrat).val1; 

请注意,括号是必要的。 这个行动很久以前(当C年轻的时候)就已经很普遍了,他们决定创build一个“速记”的方法:

 cout << kwadrat->val1; 

这些被定义为相同的。 正如你所看到的,基本上只是把*和a结合起来. 成一个单一的操作。 如果你直接处理对象或对象的引用,你可以使用. 而不是先引用一个指针:

 Kwadrat kwadrat2(2,3,4); cout << kwadrat2.val1; 

::是范围parsing运算符。 当你只需要限定名字的时候就使用它,但是你根本不处理单个对象。 这主要是为了访问一个静态数据成员:

 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相关联。 实际上,即使没有创build该types对象的实例,它也会存在。 在这种情况下,我们可以使用范围parsing运算符来访问它:

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

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

 something s; sx = 1; 

至less在内存服务的时候,早在C ++的历史上这是不被允许的,但是含义是毫不含糊的,所以他们决定允许它。

尽pipeIDE有误导性的提示,但这三个操作符有着相关但却不同的含义。

::运算符被称为作用域parsing运算符 ,它用于从命名空间或类获取其成员之一。

.->操作符用于访问对象实例的成员,并且只有在创build对象实例后才能进入操作。 你用. 如果你有一个实际的对象(或者对象的引用,在声明的types中用&声明),你可以使用->如果你有一个指向一个对象的指针(在声明的types中用*声明)。

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