There is this code:
#include <iostream>
const int c = 3;
struct A {
static int f() { return c; }
static const int c = 2;
};
int main() {
std::cout << A::f() << std::endl; // 2
return 0;
}
How does it happen that variable c defined inside class A is used in function f instead of variable c defined in global scope although global variable c is declared first?
It does not matter which variable is declared first: if a class has a variable with the same name in it, that variable trumps the global variable. Otherwise you could get existing code in a lot of trouble simply by declaring a global variable with a name of one of its member variables!
Of course your class can use scope resolution operator to reference the global c directly:
static int f() { return ::c; }
Now your program will print 3 instead of 2.
Is not a question of declaring order but of variable scope, the used variable are searched before in the current method/function after in the class/struct and a the and in the global context,
example:
#include <iostream>
const int c = 3;
struct A {
static void print() {
int c = 4
std::cout <<"Method Scope:"<< c << std::endl; // 4
std::cout <<"Class/Struct Scope:"<< A::c << std::endl; // 2 here you can use alse ::A::c
std::cout <<"Global Scope:"<< ::c << std::endl; // 3
}
static const int c = 2;
};
struct B {
static void print() {
std::cout <<"Method Scope:"<< c << std::endl; // 2
std::cout <<"Class/Struct Scope:"<< B::c << std::endl; // 2 here you can use alse ::A::c
std::cout <<"Global Scope:"<< ::c << std::endl; // 3
}
static const int c = 2;
};
struct C {
static void print() {
std::cout <<"Method Scope:"<< c << std::endl; // 3
//std::cout <<"Class/Struct Scope:"<< C::c << std::endl; //is inpossible ;)
std::cout <<"Global Scope:"<< ::c << std::endl; // 3
}
};
int main() {
A::print();
B::print();
C::print();
return 0;
}
imagine that you have long code which uses many variables, do you want them to be called instead these from a class to which function belongs? stating:
a or b
in class means
this->a
this->b
and if you want global variable to be visible you have to use it like
::a or ::b inside this function, so via:
static int f() { return ::c; }
From the standard docs, Sec 3.3.1
Every name is introduced in some portion of program text called a declarative region, which is the largest part of the
program in which that name is valid, that is, in which that name may be used as an unqualified name to refer to the
same entity. In general, each particular name is valid only within some possibly discontiguous portion of program text
called its scope. To determine the scope of a declaration, it is sometimes convenient to refer to the potential scope of
a declaration. The scope of a declaration is the same as its potential scope unless the potential scope contains another
declaration of the same name. In that case, the potential scope of the declaration in the inner (contained) declarative
region is excluded from the scope of the declaration in the outer (containing) declarative region.
this means that the potential scope is same as the scope of the declaration unless another (inner) declaration occurs. If occurred, the potential scope of the outer declaration is removed and just the inner declaration's holds, so your global variable is hidden.
Related
using namespace std;
struct A
{
int i;
A(int i_ = 13) : i(i_)
{
cout << _FUNCTION_ << "\n";
}
~A()
{
cout << _FUNCTION_ << "\n";
}
};
int main()
{
A* p = new A;
A a();
return 0;
}
When I run it, the code displays on my terminal "A::A". I get that the first A is called from first FUNCTION for "A* p" , but why does "::" appear? And the last A after "::" is from " A a(); "?
A constructor for a type has the same name as the type itself. :: is the scope resolution operator and is used to name things contained within a named scope, such as a namespace or a type.
The constructor of A is therefore A::A. The first A is the name of the type, and the second is the name of the constructor; the :: is to indicate that the constructor is declared within the scope of the type.
This mirrors the way you would define type members following a declaration with no definition. For example:
struct A
{
int i;
A(int i_ = 13);
~A();
};
// Note how we have to refer to the constructor to define it since we are
// no longer within the scope of A:
A::A(int i_) : i(i_)
{
cout << _FUNCTION_ << "\n";
}
// Similar for the destructor.
A::~A()
{
cout << _FUNCTION_ << "\n";
}
You should only see A::A in your output. Note that you only create one A value here:
A* p = new A;
You never delete p; and so you don't see the matching destructor call (A::~A) in the output.
This line does not create a variable of type A; rather, it declares a function called a that takes no arguments and returns an A value. This function is never invoked (nor defined):
A a();
This is a vexing parse (not to be confused with the most vexing parse). Clearly you intended to declare a variable, but this could be either a function or variable declaration, and the grammar prefers a function declaration.
To fix this, either remove the parens or use C++11's uniform initialization syntax:
A a; // Default initialization
A a{}; // Uniform initialization
_FUNCTION_ is a magic constant, therefore it posts the first "A" (name of the function called. Can't help with the rest though.
I am trying to create an object using placement new (I know to use smart pointers, this is just to learn). My code is as follows:
#include <vector>
#include <iostream>
#include <memory>
using namespace std; // please excuse this
// if you change like 19 to arr1 (or any other var name) instead of arr and line 40 to arr1 then it works
struct A
{
int in = 999;
A()
{cout << "A ctor\n";}
~A()
{cout << "A dtor\n";}
};
char arr[sizeof(A)];
class B
{
public:
static char arr[sizeof(A)];
const static A* a_obj;
B()
{
cout << "B ctor\n";
//cout << (a_obj->in) << endl;
}
~B()
{
cout << "B dtor\n";
}
};
const A* B::a_obj = new(arr) A;
int main()
{
B g;
}
I have created a global array named arr and another array named arrin B. It seems like when I do my placement new the arr being used is from the class as I get what I think are linker errors.
Why is this happening? why isn't the global arr being used? If i change the placement new to use my renamed global array it works. I think it has to do something with lookups but I don't have a concrete answer.
From the C++ 2017 Standard (12.2.3.2 Static data members)
2 The declaration of a non-inline static data member in its class
definition is not a definition and may be of an incomplete type other
than cv void. The definition for a static data member that is not
defined inline in the class definition shall appear in a namespace
scope enclosing the member’s class definition. In the definition at
namespace scope, the name of the static data member shall be qualified
by its class name using the :: operator. The initializer expression
in the definition of a static data member is in the scope of its
class (6.3.7).
So in this definition of the static data member
const A* B::a_obj = new(arr) A;
the unqualified name arr is at first searched in the scope of the class B. And the class B indeed declares such a name
static char arr[sizeof(A)];
If you want to use the name from the global namespace then use the qualified name
const A* B::a_obj = new(::arr) A;
Here is a demonstrative program
#include <iostream>
struct A
{
const static int N = 10;
static int n1;
static int n2;
};
const int N = 20;
int A::n1 = N;
int A::n2 = ::N;
int main()
{
std::cout << "A::n1 = " << A::n1 << std::endl;
std::cout << "A::n2 = " << A::n2 << std::endl;
return 0;
}
Its output is
A::n1 = 10
A::n2 = 20
The reason arr is attribute to the class B and not the global scope is due to unqualified name lookup rules.
Specifically:
Static data member definition For a name used in the definition of a
static data member, lookup proceeds the same way as for a name used in
the definition of a member function.
Meaning:
struct X {
static int x;
static const int n = 1; // found 1st
};
int n = 2; // found 2nd.
int X::x = n; // finds X::n, sets X::x to 1, not 2
If you are intrested you can see more information here:
http://en.cppreference.com/w/cpp/language/unqualified_lookup
As people suggested to get what you want just use:
const A* B::a_obj = new(::arr) A;
Say I declare a variable in one function like so:
void i() {
int c;
}
how would I be able to do this in a different function?
void j() {
cout << c << endl;
}
Lets start with the basics:
in C++, default storage class of variables is auto.
What this means is that variables declared inside a block will only be available inside that block after you declare them.
a block is marked with the curly braces (loops, if statements, functions, etc)
void i() {
//c is not declared here and is unavailable
int c;
//c is available
for(int i=0; i<2; i++)
{
//c is also available here, because it is declared in larger scope
}
}
//c is not recognized here because it is declared only inside the scope of i()
void j()
{
int c; //this is variable c. it has nothing to do with the c that is declared in i()
for(int i=0; i<2; i++)
{
int d; //this variable gets created and destroyed every iteration
}
//d is not available here.
}
By default, a variable that is declared inside the body of a function, will live only inside that function scope after the point of declaration.
In your question you have not described how you want the two functions to communicate, thus it is difficult to point to a suitable approach.
If you want to pass the same value between functions you should read into argument passing and function return values. There is another way which is global variables, not recommended unless absolutely needed, but definitely something you need to learn.
void j(const int c)
{
std::cout << c << std::endl;
}
Then just call it from your function using:
j(c);
The best approach depends on what you actually do with c. Namely if c is not unique to an invocation of i() then you can use a global variable to get access it anywhere:
int c;
void i(){
c = c++; //uses c, pun intended
}
void j(){
cout << c << endl;
c++; //can change c
}
If a unique c is used every time i()is called, then you can define it in i() and have to pass it to j() from within i(), otherwise j() does not know where c is:
void i(){
int c;
j(c);
}
void j(int c){
cout << c << endl;
c++; //cannot change c in i()
}
Note that above c in i() and c in j() are not the same variable. If you change c in j() it will not be changed in i(), where as with the global approach it would be.
If want the variable to be unique to i() but accessible to j() you would instead pass the variable either by a pointer(not shown) or refence(shown below):
void i(){
int c=0;
j(c);
}
void j(int &c){
cout << c << endl;
c++; //can change c in i()
}
Note: The terminology here is rather casual, I didn't even use the word scope which you may want to learn more about.
The variable c wouldn't exist in the context where j is called, so you'd have to pass it on as a global variable or a return value.
int i(){
int c = 2;
return c;
}
int i() will return c, which can be passed on to other constructors.
void j(const int c){
std::cout << c << std::endl;
}
Or rather, call i inside of j.
void j(){
int cr = i();
std::cout << cr << std::endl
}
Can there be a member variable in a class which is not static but which needs to be defined
(as a static variable is defined for reserving memory)? If so, could I have an example? If not, then why are static members the only definable members?
BJARNE said if you want to use a member as an object ,you must define it.
But my program is showing error when i explicitly define a member variable:
class test{
int i;
int j;
//...
};
int test::i; // error: i is not static member.
In your example, declaring i and j in the class also defines them.
See this example:
#include <iostream>
class Foo
{
public:
int a; // Declares and defines a member variable
static int b; // Declare (only) a static member variable
};
int Foo::b; // Define the static member variable
You can now access a by declaring an object of type Foo, like this:
Foo my_foo;
my_foo.a = 10;
std::cout << "a = " << my_foo.a << '\n';
It's a little different for b: Because it is static it the same for all instance of Foo:
Foo my_first_foo;
Foo my_second_foo;
Foo::b = 10;
std::cout << "First b = " << my_first_foo.b << '\n';
std::cout << "Second b = " << my_second_foo.b << '\n';
std::cout << "Foo::b = " << Foo::b << '\n';
For the above all will print that b is 10.
in that case, you would use the initialization list of test's constructor to define the initial values for an instance like so:
class test {
int i;
int j;
//...
public:
test() : i(-12), j(4) {}
};
That definition reserves space for one integer, but there'll really be a separate integer for every instance of the class that you create. There could be a million of them, if your program creates that many instances of test.
Space for a non-static member is allocated at runtime each time an instance of the class is created. It's initialized by the class's constructor. For example, if you wanted the integer test::i to be initialized to the number 42 in each instance, you'd write the constructor like this:
test::test(): i(42) {
}
Then if you do
test foo;
test bar;
you get two objects, each of which contains an integer with the value 42. (The values can change after that, of course.)
In C++, what is the scope resolution ("order of precedence") for shadowed variable names? I can't seem to find a concise answer online.
For example:
#include <iostream>
int shadowed = 1;
struct Foo
{
Foo() : shadowed(2) {}
void bar(int shadowed = 3)
{
std::cout << shadowed << std::endl;
// What does this output?
{
int shadowed = 4;
std::cout << shadowed << std::endl;
// What does this output?
}
}
int shadowed;
};
int main()
{
Foo().bar();
}
I can't think of any other scopes where a variable might conflict. Please let me know if I missed one.
What is the order of priority for all four shadow variables when inside the bar member function?
Your first example outputs 3. Your second outputs 4.
The general rule of thumb is that lookup proceeds from the "most local" to the "least local" variable. Therefore, precedence here is block -> local -> class -> global.
You can also access each most versions of the shadowed variable explicitly:
// See http://ideone.com/p8Ud5n
#include <iostream>
int shadowed = 1;
struct Foo
{
int shadowed;
Foo() : shadowed(2) {}
void bar(int shadowed = 3);
};
void Foo::bar(int shadowed)
{
std::cout << ::shadowed << std::endl; //Prints 1
std::cout << this->shadowed << std::endl; //Prints 2
std::cout << shadowed << std::endl; //Prints 3
{
int shadowed = 4;
std::cout << ::shadowed << std::endl; //Prints 1
std::cout << this->shadowed << std::endl; //Prints 2
//It is not possible to print the argument version of shadowed
//here.
std::cout << shadowed << std::endl; //Prints 4
}
}
int main()
{
Foo().bar();
}
It should print out 3. The basic rule is mostly to work your way backward through the file to the most recent definition the compiler would have seen (edit: that hasn't gone out of scope), and that's what it uses. For variables that are local to a class, you follow the same except that all class variables are treated as if they were defined at the beginning of the class definition. Note that this is more or less unique to classes though. For example, given code like:
int i;
int x() {
std::cout << i << '\n'; // prints 0;
int i=1;
}
Even though there is an i that's local to the function, the most recent definition seen where cout is used is the global, so that's what the i in that expression refers to. If, however, this were in a class:
int i;
class X {
void y() { std::cout << i << "\n"; }
X() : i(2) {}
int i;
};
Then the cout expression would refer to X::i even though its definition hasn't been seen yet when y is being parsed.