This question already has answers here:
When do I use a dot, arrow, or double colon to refer to members of a class in C++?
(4 answers)
Closed 4 months ago.
I created a class called Kwadrat. The class has three int fields. My Development Environment suggests that I access the fields from Kwadrat created objects via the :: & -> operators. I tried both operators, and found that the -> operator is able to successfully access the data in the objects fields, although, the same cannot be said for the -> operator.
I have also found that the . operator will access class members as well. I am confused, and don't understand why there are three members for accessing object members &/or methods. Can someone please explain to me what the difference is between the three operators?
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.-> 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();
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();
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()
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.
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;
}
-> is for pointers to a class instance
. is for class instances
:: is for classnames - for example when using a static member
The '::' is for static members.
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;
}
Related
Inside setMyInt function I have used two statements to set myInt variable. Though both of them gives me the same result. Is there any conceptual difference in working of them?
#include <iostream>
using namespace std;
class Bar{
int myInt;
public:
const int getMyInt() const {
return myInt;
}
void setMyInt(int myInt) {
Bar::myInt = myInt;
this->myInt=myInt;
}
};
int main(){
Bar obj;
obj.setMyInt(5);
cout<<obj.getMyInt();
return 0;
}
You can't really compare them, and they are not interchangeable, but because in C++ you can leave certain things out in certain cases, here it looks like they are.
In fact, both lines are short for:
this->Bar::myInt = myInt;
This means, set the value of the object Bar::myInt (the member called myInt in the scope of the class Bar), which is encapsulated by the object pointed to by this, to the value of the (other) variable myInt.
You can leave out Bar:: because this is a Bar* so that's implicit; you can leave out this-> because you're in a member function so that's implicit too.
More generally, -> performs a pointer dereference and object access, whereas :: is the "scope resolution operator" which fully qualifies a name.
“->” is used as a pointer
“.” Is used for object members variables/ methods
“::” Is used for static variables/ methods or for objects from another scope.
Why can I use double colons in functions and classes not defined but I can't use in variables ??
Example:
#include <iostream>
using namespace std;
class Person{
public:
int age;
string name();
};
int Person::age = 10; //It outputs an error
string Person::name(){ //It doesn't
return "n";
}
Why can I use double colons in functions and classes not defined but I can't use in variables ??
age is an instance field, it exists in multiple places in memory - one for each Person that exists.
I'll now expand in detail about what the :: operator does, how to use it, and how static class members compare to instance members:
The :: operator:
The :: (the scope-resolution operator) has multiple uses in C++:
If you're familiar with Java, C# or JavaScript then it can be likened to the dot dereference or "navigation operator" . (e.g. namespace.Class.Method().Result) - except C++ uses a different operators for different kinds of navigation and dereferencing:
. is the member-access operator, similar to C - it's only applicable for "object values" and references (foo&), not pointers (foo*).
-> is another member-access operator for pointer types, note that this operator can be overridden but . cannot (overridin -> is risky but it improves the ergonomics of smart-pointer libraries when done correctly).
:: is the scope-resolution operator - it has a few different uses:
Namespace navigation - whereas Java and C# use . to navigate packages and namespaces, C++ uses ::, for example: using std::time.
When unqualified, it's also used to reference the global namespace, e.g. ::std which is handy if you're writing code which is already in a namespace.
It's also used to access static members of types - typically an actual static member (a static method or field) but also items like enum class (scoped enumeration) values (e.g. SomeEnumClass::value_name)
Finally, it's also used to select a specific base method when dealing with virtual method implementations: it's used when an overridden method needs to call a base implementation in a superclass - C++ does not have the singular base or super keywords that C# and Java have (respectively) because C++ allows multiple inheritance, so you must specify the specific parent class name: How to call a parent class function from derived class function?
Anyway, in your case, it looks like you're confused about what instance and static members actually mean, so here is an illustration:
class Person {
public:
int height; // each Person has their own height, so this is an instance member
static int averageHeight; // but an individual Person doesn't have an "average height" - but a single average-height value can be used for all Persons, so this is a shared ("static") value.
int getAverageHeight() { // this is an instance method, btw
return Person::averageHeight; // use `Person::` to unambiguously reference a static member of `Person`
}
Person()
: height(0) {
// instance members should be initialized in the constructor!
}
}
// This will create an array of 10 people (10 different object instances).
// Each Person object (an instance) will have its own `height` in memory
Person* multiplePeople = new Person[10];
// btw, you probably should use `std::array` with an initializer instead:
// array<Person,10> multiplePeople{}; // <-- like this
// This sets a value to the `staticField` member, which exists only once in memory, that is, all Person instances share the same value for this member...
Person::averageHeight = 175; // 175cm
// ...for example:
assert( 175 == multiplePeople[3]->getAverageHeight() );
assert( 175 == multiplePeople[6]->getAverageHeight() );
// However instance members can have different values for each instance:
multiplePeople[3]->height = 170;
multiplePeople[6]->height = 180;
// Btw `height` is initialized to 0 in each Person's constructor.
assert( 170 != multiplePeople[0]->height );
assert( 180 != multiplePeople[7]->height );
I have found the class Kwadrat. The author used three types of operator ::, . and ->. The arrow is the one that only works. What's the difference between those three?
#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;
}
:: names a type within a namespace, a variable within a namespace, a static variable in a class, or a type in a class.
. names an instance variable or member function
a->b is syntactic sugar for (*a).b.
-> works on pointers, . on objects and :: on namespaces. Specifically:
Use -> or . when accessing a class/struct/union member, in the first case through a pointer, in the latter through a reference.
Use :: to reference the function inside a namespace or a class (namespaces), for instance, when defining methods declared with the class.
x->y is equivalent to (*x).y. That is, -> dereferences the variable before getting the field while the dot operator just gets the field.
x::y looks up y in namespace x.
The use cases are:
-> is used when you have a pointer
. is used when you have an object instance
:: is used when you have a static member or a namespace
The -> is the equivalent of saying (*Kwadrat_pointer).value. You use it when you have an object pointer calling object methods or retrieving object members.
The . operator is used to access the methods and members in the object that is calling it (that is, the object on the left side of the ".").
The :: operator is called the scope operator. It tells your program where to look, for example when defining a class method outside of the class declaration.
When we declare some variable inside class or struct in C/C++, we have to make an object of class or struct to allocate memory for the variable.
Why can't we just access these variables without any object?
Well, the answer is really: because that's the whole point of this language feature. The very idea of a data member of a class is for it to be an integral part of class object. It begins its life together with the entire class object and it ends its life together.
If you have two class objects, you have two completely independent sets of data members. If you have 50 class objects, you have 50 completely independent sets of data members. If you have zero class objects, you have no sets of data members to access. In other words, you cannot access these "variables" without a class object simply because they do not exist without a class object.
You are not really "declaring a variable" when you declaring a data member of a class in a class definition. Class definition simply describes the layout of class type. By itself it produces nothing physical, i.e noting that would live in data memory, noting you can physically access.
Meanwhile, C++ language has such concept as static member of the class. Static data members of the class are not associated with specific class objects. They exist independently. In fact, static data members are just ordinary global variables covered by a fairly thin layer of C++-specific "syntactic sugar" (more elaborate naming, access control etc.) Static data members of the class can be accessed as ordinary variables, without any object.
In other words, it is not a question of "why?" but rather a question of what you need. If you want non-static data member functionality, use non-static data members. If you want static data member functionality... well, you get the idea.
A class is just a 'layout' used to specify how instanced object will be constructed, destroyed and how they will behave. For an imaged comparizon with buildings: a class is the plan used to build the house. The object is the house itself.
If you want variable without objects, use global variables. You can put them in a namespace:
namespace test
{
int answer = 42; // Initialization is optional
}
// ...
void f()
{
// Use it like this:
test::answer = 0;
}
You can also use static members:
class MyClass
{
public:
static int value;
};
Usually, you declare a member variable inside a class precisely because you want it to be part of an object of that class type. That's what that language feature is for: to allow you to have many distinct objects, each with its own state independent of any other object.
In C++ (but not C), you can declare it static if you want a single variable, independent of any object. This will have static storage duration, just like a variable declared outside a class. In C, global variables are the only option if you want something like this.
For example:
struct thing {
int a; // part of a "thing" object
static int b; // not part of a "thing"
};
// Static variables need a definition, in exactly one source file
int thing::b;
int main() {
thing::b = 1; // OK: no object needed
thing::a = 2; // ERROR: object needed
thing t1;
t1.a = 3; // OK: accessing object member
t1.b = 4; // OK: equivalent to "thing::b"
thing t2;
t2.a = 5; // OK: accessing object member
t2.b = 6; // OK: equivalent to "thing::b"
std::cout << t1.a; // prints 3
std::cout << t2.a; // prints 5 - independent of t1.a
std::cout << t1.b; // prints 6
std::cout << t2.b; // prints 6 - same variable as t1.b (aka thing::b)
}
Using the static keyword:
class A {
public:
static int varaible;
};
int A::variable = 5;
Then you can access the variable without an object anytime. As follows.
A::varaible = 25;
Things you'll need to know:
You will need to use the scope operator(::) to access a static member.
Definition of a static member must be done outside of the class. The above statement int A::variable = 5; is an definition of a static member.
All objects of type A (included inherited objects) share a static member. [1]
[1]
A a;
A b;
a::variable == b::variable == 25;
//if we change a::variable
a::variable = 26;
//b::variable has the same value.
b::variable == a::variable == 26;
This question already has answers here:
When do I use a dot, arrow, or double colon to refer to members of a class in C++?
(4 answers)
Closed 8 years ago.
Apologies for a question that I assume is extremely basic.
I am having trouble finding out online the difference between the operator :: and . in C++
I have a few years experience with C# and Java, and am familiar with the concept of using . operator for member access.
Could anyone explain when these would be used and what the difference is?
Thanks for your time
The difference is the first is the scope resolution operator and the second is a member access syntax.
So, :: (scope resolution) can be used to access something further in a namespace like a nested class, or to access a static function. The . period operator will simply access any visible member of the class instance you're using it on.
Some examples:
class A {
public:
class B { };
static void foo() {}
void bar() {}
};
//Create instance of nested class B.
A::B myB;
//Call normal function on instance of A.
A a;
a.bar();
//Call the static function on the class (rather than on an instance of the class).
A::foo();
Note that a static function or data member is one that belongs to the class itself, whether or not you have created any instances of that class. So, if I had a static variable in my class, and crated a thousand instances of that class, there's only 1 instance of that static variable still. There would be 1000 instances of any other member that wasn't static though, one per instance of the class.
One more interesting option for when you come to it :) You'll also see:
//Create a pointer to a dynamically allocated A.
A* a = new A();
//Invoke/call bar through the pointer.
a->bar();
//Free the memory!!!
delete a;
Dynamic memory can be a little more confusing if you haven't learned it yet, so I won't go into details. Just wanted you to know that you can access members with { :: or . or -> } :)
in C++ :: is the scope resolution operator. It is used to distinguish namespaces, and static methods, basically any case you don't have an object. Where . is used to access things inside an object.
C# uses the . operator for both of them.
namespace Foo
{
public class Bar
{
public void Method()
{
}
public static void Instance()
{
}
}
}
in C# you would write code like this:
var blah = new Foo.Bar();
blah.Method();
but the equivalent C++ code would look more like this:
Foo::Bar blah;
blah.Method();
But note that the static method would also be accessed using the scope resolution operator, because you're not referencing an object.
Foo::Bar::Instance();
Where again, the C# code would only use the dot operator
Foo.Bar.Instance();
:: is for namespaces and static member access. C# uses the dot-operator for namespaces instead.
. is for non-static member access.
Not an exhaustive delineation, but it's the relevant bits that may confuse you in light of C# and Java.
For further information, see
IBM - Scope Resolution Operator
IBM - Dot Operator
:: is the scope resolution operator, so when you are resolving a scope, such as a namespace or class, you use that. For member access, you have .
The scope operator :: may be hard to understand if you don't understand namespaces or classes. A namespace is like a container for the names of various things in your code. They're generally used to disambiguate names that are common across libraries. Say both namespaces std and example have the function foobar(). So the compiler knows which function you want to use, you prepend it as either std::foobar() or example::foobar().
The :: operator can also be used when telling the compiler you want to define a function declared in a class or structure. For instance:
class foobar()
{
public:
void hello();
int number; //assume there is a constructor that sets this to 5
}
void foobar::hello()
{
cout << "Hello, world!" << endl;
}
The . operator is used when you wish to use a member of a class or structure. For instance:
foobar foo;
foo.hello();
cout << foo.number << endl;
Assuming the class is completed by writing a constructor, the output of this would be expected to be:
Hello, world!
5
You use the . operator the same in java, when accessing members of a class once its created in the program.
the :: is used in number of cases:
When you define a method in the .h/.cpp of a certain class, write
class::methodName()
either for prototyping it, or implementing it.
Also, if you don't explicitly state what namespace you use, you'd have to to use it
std::cout << "This is the output";
instead of just using cout << "This is the output;
Maybe there are more, but i don't remember right now, my C++ is a bit rusty.
In C++, :: is for identifying scope. This can mean namespace scope or class scope.
Eg.
int x;
namespace N {
int x;
struct foo {
static double x;
double y;
};
struct bar: public foo {
double y;
};
}
int main()
{
int x; // we have a local, hiding the global name
x = ::x; // explicitly identify the x in global scope
x += N::x; // explicitly identify the x in namespace N
N::foo::x = x; // set the static member of foo to our local integer
N::foo f;
f.y = f.x; // the static member is implicitly scoped by the object
f.y += N::foo::x; // or explicitly scoped
N::bar b;
assert(b.x == N::foo::x); // this static member is inherited
b.y = b.x; // we get N::bar::y by default
b.N::foo::y = b.y; // explicitly request the hidden inherited one
}
// we need to define the storage for that static somewhere too ...
int N::foo::x (0.0);