在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/struct
或namespace
静态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.
在这种情况下,因为x
是static
,所以它不与任何特定的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; }