If a C++ class member function accesses a variable name that is overloaded with definitions both as a member variable of the class and a variable in the global scope of the member function’s definition, which one will the member function actually access? The scenario is like this:
SomeClass.h:
class SomeClass
{
int Num;
void OperateOnNum();
};
SomeClass.cpp:
#include "SomeClass.h"
int Num;
void SomeClass::OperateOnNum()
{
Num = 0;
}
Which Num will OperateOnNum operate on? Neither Microsoft Visual Studio 2013 nor GCC (Version: gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2) issues a warning.
The class variable shadows the global variable. If you want to access the global variable do it like this:
void SomeClass::OperateOnNum()
{
::Num = 0;
}
There's no warnings, because that's just how the language works.
You can always use this and global scope resolution to dissambiguate between the two
this->Num; // refers to the member Num
::Num; // refers to the global Num
A good design though, shouldn't have to resort to such methods. You can mark member names and globals (which are a "don't" on their own) accordingly :
_name; // member name prefixed with _
m_name; // member name prefixed with m_
global_name; // global name - prefixed with global_
In this case the class member parameter shadows the global variable. Thus you see it in the scope of the method.
Related
If a C++ class member function accesses a variable name that is overloaded with definitions both as a member variable of the class and a variable in the global scope of the member function’s definition, which one will the member function actually access? The scenario is like this:
SomeClass.h:
class SomeClass
{
int Num;
void OperateOnNum();
};
SomeClass.cpp:
#include "SomeClass.h"
int Num;
void SomeClass::OperateOnNum()
{
Num = 0;
}
Which Num will OperateOnNum operate on? Neither Microsoft Visual Studio 2013 nor GCC (Version: gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2) issues a warning.
The class variable shadows the global variable. If you want to access the global variable do it like this:
void SomeClass::OperateOnNum()
{
::Num = 0;
}
There's no warnings, because that's just how the language works.
You can always use this and global scope resolution to dissambiguate between the two
this->Num; // refers to the member Num
::Num; // refers to the global Num
A good design though, shouldn't have to resort to such methods. You can mark member names and globals (which are a "don't" on their own) accordingly :
_name; // member name prefixed with _
m_name; // member name prefixed with m_
global_name; // global name - prefixed with global_
In this case the class member parameter shadows the global variable. Thus you see it in the scope of the method.
In C++, what is the purpose of the scope resolution operator when used without a scope? For instance:
::foo();
It means global scope. You might need to use this operator when you have conflicting functions or variables in the same scope and you need to use a global one. You might have something like:
void bar(); // this is a global function
class foo {
void some_func() { ::bar(); } // this function is calling the global bar() and not the class version
void bar(); // this is a class member
};
If you need to call the global bar() function from within a class member function, you should use ::bar() to get to the global version of the function.
A name that begins with the scope resolution operator (::) is looked up in the global namespace. We can see this by looking at the draft C++ standard section 3.4.3 Qualified name lookup paragraph 4 which says (emphasis mine):
A name prefixed by the unary scope operator :: (5.1) is looked up in global scope, in the translation unit where it is used. The name shall be declared in global namespace scope or shall be a name whose declaration is visible in global scope because of a using-directive (3.4.3.2). The use of :: allows a global name to be referred to even if its identifier has been hidden (3.3.10).
As the standard states this allows us to use names from the global namespace that would otherwise be hidden, the example from the linked document is as follows:
int count = 0;
int main(void) {
int count = 0;
::count = 1; // set global count to 1
count = 2; // set local count to 2
return 0;
}
The wording is very similar going back to N1804 which is the earliest draft standard available.
Also you should note, that name resolution happens before overload resolution. So if there is something with the same name in your current scope then it will stop looking for other names and try to use them.
void bar() {};
class foo {
void bar(int) {};
void foobar() { bar(); } // won't compile needs ::bar()
void foobar(int i) { bar(i); } // ok
}
When you already have a function named foo() in your local scope but you need to access the one in the global scope.
My c++ is rusty but I believe if you have a function declared in the local scope, such as foo() and one at global scope, foo() refers to the local one. ::foo() will refer to the global one.
referring to the global scope
I have a static variable in the class.
I am Initializing that in the global scope, its works fine.
But
When I try to Initialize in the main linker throws an error.
Why it so.
class Myclass{
static int iCount;
} ;
int main(){
int Myclass::iCount=1;
}
And In global scope why I have to specify the variable type
like
int Myclass::iCount=1;
As In my class I am definig iCount as integer type why not.
Myclass::iCount =1 ; in //Global scope
The section $9.4.2/7 from the C++ Standard says,
Static data members are initialized
and destroyed exactly like non-local
objects (3.6.2, 3.6.3).
Note the phrases "initialized" and "exactly like non-local objects". Hope that explains why you cannot do that.
In fact, static members are more like global objects accessed through Myclass::iCount. So, you've to initialize them at global scope (the same scope at which class is defined), like this:
class Myclass{
static int iCount;
} ;
int Myclass::iCount=1;
int main(){
/*** use Myclass::iCount here ****/
}
Similar topic:
How do static member variables affect object size?
Because C++ syntax doesn't allow this. You need to instantiate your static variable outside of the scope of some function.
Besides you forget a semicolon ; after your class ending bracket.
this is the correct C++. Outside of a function, in a cpp file. the initialisation is done at the beginning/launching of the executable. ( even before calling main() );
//main.h
class Myclass{
static int iCount;
}; // and don't forget this ";" after a class declaration
//main.cpp
int Myclass::iCount=1;
int main(){
}
From C++ standard (§8.5/10):
An initializer for a static member is in the scope of the member’s class.
class Myclass has global scope and you tried to initialize its static member in the narrower scope - of the function main.
The static initialisation occurs before main is called by the run-time initialisation.
Placing it within a function is not allowed because that is where locally scoped objects are declared. It would be confusing and ambiguous to allow that.
If you go to the accepted answer of this post
Could someone please elaborate on why he uses:
double temp = ::atof(num.c_str());
and not simply
double temp = atof(num.c_str());
Also, is it considered a good practice to use that syntax when you use "pure" global functions?
It says use the global version, not one declared in local scope. So if someone's declared an atof in your class, this'll be sure to use the global one.
Have a look at Wikipedia on this subject:
#include <iostream>
using namespace std;
int n = 12; // A global variable
int main() {
int n = 13; // A local variable
cout << ::n << endl; // Print the global variable: 12
cout << n << endl; // Print the local variable: 13
}
:: is the scope resolution operator. Its use in this scenario, as a unary operator, is to ensure that the name (atof) is always looked up in the global scope -- this can be useful to prevent name hiding from interfering with the lookup.
The :: operator is scope resolution operator.
when used with class specifier as like A::a, it is to access the data memeber a of the class A.
when used without any specifier, it access the global variable.
It is used mainly in the following contests.
To refer to the global variables.
To refer to the static members of the class
To avoid ambiguites, when a class inherits from multiple [ non-virtual
base ] classes.
With using directive, to use the base class functions in the derived class, when there is a function in base class with name same as that of the derived class, but for a different type.
To access the functions defined in the global scope, when you have a function defined with the same signature, as in double temp = ::atof(num.c_str());
To create objects of the nested classes.
Lets say you have two versions of a function f() one defined outside a namespace and one defined inside. Now lets say you have one more function g() in the same namespace. Now if you do f() inside g() it will call the one defined in the same namespace. But if you want to call the global version you need to do ::f()
::func() means that this function is not affiliated with any specific class. It is used when there exist many functions with the same name, and to avoid confusion between the one you want and specific member functions you precede the function name with the scope operator.
From C++ Primer, 4th edition, section 17.2.1:
"Names defined at global scope - names declared outside any class, function, or namespace - are defined inside the global namespace. The global namespace is implicitly declared and exists in every program. Each file that defines entities at global scope adds those names to the global namespace.
The scope operator can be used to refer to members of the global namespace. Because the global namespace is implicit, it does not have a name; the notation
::member_name
refers to a member of the global namespace."
In C++, what is the purpose of the scope resolution operator when used without a scope? For instance:
::foo();
It means global scope. You might need to use this operator when you have conflicting functions or variables in the same scope and you need to use a global one. You might have something like:
void bar(); // this is a global function
class foo {
void some_func() { ::bar(); } // this function is calling the global bar() and not the class version
void bar(); // this is a class member
};
If you need to call the global bar() function from within a class member function, you should use ::bar() to get to the global version of the function.
A name that begins with the scope resolution operator (::) is looked up in the global namespace. We can see this by looking at the draft C++ standard section 3.4.3 Qualified name lookup paragraph 4 which says (emphasis mine):
A name prefixed by the unary scope operator :: (5.1) is looked up in global scope, in the translation unit where it is used. The name shall be declared in global namespace scope or shall be a name whose declaration is visible in global scope because of a using-directive (3.4.3.2). The use of :: allows a global name to be referred to even if its identifier has been hidden (3.3.10).
As the standard states this allows us to use names from the global namespace that would otherwise be hidden, the example from the linked document is as follows:
int count = 0;
int main(void) {
int count = 0;
::count = 1; // set global count to 1
count = 2; // set local count to 2
return 0;
}
The wording is very similar going back to N1804 which is the earliest draft standard available.
Also you should note, that name resolution happens before overload resolution. So if there is something with the same name in your current scope then it will stop looking for other names and try to use them.
void bar() {};
class foo {
void bar(int) {};
void foobar() { bar(); } // won't compile needs ::bar()
void foobar(int i) { bar(i); } // ok
}
When you already have a function named foo() in your local scope but you need to access the one in the global scope.
My c++ is rusty but I believe if you have a function declared in the local scope, such as foo() and one at global scope, foo() refers to the local one. ::foo() will refer to the global one.
referring to the global scope