C + + 中“ :”.”和“->”的区别是什么

我创建了一个名为 Kwadrat的类。该类有三个 int字段。我的 发展环境建议我通过 int0和 int1操作符从 Kwadrat创建的对象访问字段。我尝试了这两个操作符,发现 int1操作符能够成功地访问对象字段中的数据,尽管对于 int1操作符不能这样说。 我还发现,.操作符也将访问类成员。我很困惑,不明白为什么有三个成员用于访问对象成员和/或方法。谁能给我解释一下这三个操作员之间的区别?


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




146592 次浏览

1.-> for accessing object member variables and methods via pointer to object

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

2.. for accessing object member variables and methods via object instance

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

3.:: for accessing static variables and methods of a class/struct or namespace. It can also be used to access variables and functions from another scope (actually class, struct, namespace are scopes in that case)

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

The '::' is for static members.

-> is for pointers to a class instance

. is for class instances

:: is for classnames - for example when using a static member

In C++ you can access fields or methods, using different operators, depending on it's type:

  • ClassName::FieldName : class public static field and methods
  • ClassInstance.FieldName : accessing a public field (or method) through class reference
  • ClassPointer->FieldName : accessing a public field (or method) dereferencing a class pointer

Note that :: should be used with a class name rather than a class instance, since static fields or methods are common to all instances of a class.

class AClass{
public:
static int static_field;
int instance_field;


static void static_method();
void method();
};

then you access this way:

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();

Others have answered the different syntaxes, but please note, when you are doing your couts, you are only using ->:

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

Put very simple :: is the scoping operator, . is the access operator (I forget what the actual name is?), and -> is the dereference arrow.

:: - Scopes a function. That is, it lets the compiler know what class the function lives in and, thus, how to call it. If you are using this operator to call a function, the function is a static function.

. - This allows access to a member function on an already created object. For instance, Foo x; x.bar() calls the method bar() on instantiated object x which has type Foo. You can also use this to access public class variables.

-> - Essentially the same thing as . except this works on pointer types. In essence it dereferences the pointer, than calls .. Using this is equivalent to (*ptr).method()

The three operators have related but different meanings, despite the misleading note from the IDE.

The :: operator is known as the scope resolution operator, and it is used to get from a namespace or class to one of its members.

The . and -> operators are for accessing an object instance's members, and only comes into play after creating an object instance. You use . if you have an actual object (or a reference to the object, declared with & in the declared type), and you use -> if you have a pointer to an object (declared with * in the declared type).

The this object is always a pointer to the current instance, hence why the -> operator is the only one that works.

Examples:

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

You have a pointer to an object. Therefore, you need to access a field of an object that's pointed to by the pointer. To dereference the pointer you use *, and to access a field, you use ., so you can use:

cout << (*kwadrat).val1;

Note that the parentheses are necessary. This operation is common enough that long ago (when C was young) they decided to create a "shorthand" method of doing it:

cout << kwadrat->val1;

These are defined to be identical. As you can see, the -> basically just combines a * and a . into a single operation. If you were dealing directly with an object or a reference to an object, you'd be able to use the . without dereferencing a pointer first:

Kwadrat kwadrat2(2,3,4);


cout << kwadrat2.val1;

The :: is the scope resolution operator. It is used when you only need to qualify the name, but you're not dealing with an individual object at all. This would be primarily to access a static data member:

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.

In this case, since x is static, it's not associated with any particular instance of something. In fact, it will exist even if no instance of that type of object has been created. In this case, we can access it with the scope resolution operator:

something::x = 10;


std::cout << something::x;

Note, however, that it's also permitted to access a static member as if it was a member of a particular object:

something s;


s.x = 1;

At least if memory serves, early in the history of C++ this wasn't allowed, but the meaning is unambiguous, so they decided to allow it.