This question is an extension to:
Class method access to it's data members
The take away from the question was that whenever a class method is called, it is implicitely passed the address of the object which helps it access the data members of the class using a 'this*'.
The follow up question is:
How are the static methods of the class able to access the static data members of the class?
The argument remains the same. A function can only access the local variables loaded on the stack.
Are the static data members or their address loaded onto the static function stack implicitely?
If no, how does it work?
The reason is because both are not bound to an instance of that class.
For e.g.
class test
{
public:
static int i=5;
static int getI(){return i;}
};
You can access i like:
int a=test::i;
or like
int a=test::getI();
i is stored in the global data part of the program. It is not bound to an object, therefore it is also identical for every instance created. You can access i without create an instance of class test. class test merely a namespace in this situation. There is no memory magic.
Related
Say I have a class and I have a static member in it, but I don't create any objects of that type. Will the memory be occupied for the static variable? If it would be occupied, what is the point of putting it in a class?
No.
Static members don't belong to the instances of class. They don't increase instances and class size even by 1 bit!
struct A
{
int i;
static int j;
};
struct B
{
int i;
};
std::cout << (sizeof(A) == sizeof(B)) << std::endl;
Output:
1
That is, size of A and B is exactly the same. Static members are more like global objects accessed through A::j.
See demonstration at ideone : http://www.ideone.com/YeYxe
$9.4.2/1 from the C++ Standard (2003),
A static data member is not part of
the subobjects of a class. There is
only one copy of a static data member
shared by all the objects of the
class.
$9.4.2/3 and 7 from the Standard,
once the static data member has been
defined, it exists even if no objects
of its class have been created.
Static data members are initialized
and destroyed exactly like non-local
objects (3.6.2, 3.6.3).
As I said, static members are more like global objects!
The C++ standard doesn't explicitly state when static memory is allocated, as long as it is available on first use. That said, it is most likely allocated during program initialization, thus guaranteeing its presence as soon as it is required, without needing special-case code to detect and perform allocation on access.
The purpose of putting static data into a class is the same as putting any other data into classes. By putting the data into a class structure, you are defining an encapsulating namespace, as well as being able to control access using accessor and mutator methods; this, in turn, will allow you to validate data going into the static memory store, and to ensure consistency throughout the use of this data.
Static variables are stored in a special memory area called BSS, while instances of a class are stored in a heap or on a stack. So, static members are stored separately.
Is it possible to access non static data members outside their class? Say you have an example like the following. I know it does not make much sense as an example, but I just want to understand how to access a non static data member. If the following is compiled it generates an error:
C.h|70|error: invalid use of non-static data member ‘C::age’|
//C.h
class C{
public:
int age;
};
int getAge();
//C.cpp
C::C()
{
age = 0;
}
int getAge(){
return (C::age);
}
Non-static members are instance dependent. They are initialized when a valid instance is initialized.
The problem with your example is that, it tries to access a non-static member through the class interface without first initializing a concrete instance. This is not valid.
You can either make it static:
class C{
public:
static int age;
};
which requires you to also define age before using at runtime by: int C::age = 0. Note that value of C::age can be changed at runtime if you use this method.
Or, you can make it const static and directly initialize it like:
class C{
public:
const static int age = 0;
};
In this case, value of C::age is const.
Both of which will let you get it without an instance: C::age.
Without making it static, you would have to create a value:
Either an lvalue:
C c;
return c.age;
or an rvalue:
return C().age;
// or
return C{}.age;
The problem with your code is that you try to access the age member without creating an instance of the class. Non-static data members of a class are only accessible through an instance of the class, and in your case no instance is created.
The reason why you can't is because local variables are allocated at runtime onto the stack - you can obtain its position if you really wanted to with some inline asm but it would require some debugging to obtain the stack position and the later (after the function) you want to access it the more likely it will have long been overwritten by something else.
Suppose I have the following class:
class Test
{
int num;
public:
Test(int x):num(x){}
Test(const Test &rhs):num(rhs.num+1){}
};
int main()
{
Test test(10);
Test copy = test;
}
The num in the copy should be 11, and my question is about inside the copy constructor, why can we access the private member num of test using num to initialize the num in the copy? What is confusing me is that if you type cout<<test.num<<endl, of course it's wrong because you are trying to access the private num, but if you pass the test by reference to the copy constructor, it works, can anybody tell me what is going on here?
Private members are private to the class itself, not the instances of the class.
Access limitations are per-class, not per-object.
"private" means -- can only be accessed from within the same class.
"protected" means -- can be accessed from within the same class, and can also be accessed from within derived-classes (in derived classes, protected non-static members can only be accessed through variables with derived class type).
"public" means -- can be accessed by anything.
The point of access limitations is to limit the region of code that has to be inspected in order to understand where the values are used, rather than to stop code from using the values.
private doesn't mean private to the object instance. It means private to that class. An instance of a class T can access private members of other instances T. Similarly, a static method in a class T can access private members of instances of T.
If private restricted access to only the individual instance, it would make objects non-copyable, since as you pointed out, the copy constructor would not be able to read data from the original instance.
Say I have a class and I have a static member in it, but I don't create any objects of that type. Will the memory be occupied for the static variable? If it would be occupied, what is the point of putting it in a class?
No.
Static members don't belong to the instances of class. They don't increase instances and class size even by 1 bit!
struct A
{
int i;
static int j;
};
struct B
{
int i;
};
std::cout << (sizeof(A) == sizeof(B)) << std::endl;
Output:
1
That is, size of A and B is exactly the same. Static members are more like global objects accessed through A::j.
See demonstration at ideone : http://www.ideone.com/YeYxe
$9.4.2/1 from the C++ Standard (2003),
A static data member is not part of
the subobjects of a class. There is
only one copy of a static data member
shared by all the objects of the
class.
$9.4.2/3 and 7 from the Standard,
once the static data member has been
defined, it exists even if no objects
of its class have been created.
Static data members are initialized
and destroyed exactly like non-local
objects (3.6.2, 3.6.3).
As I said, static members are more like global objects!
The C++ standard doesn't explicitly state when static memory is allocated, as long as it is available on first use. That said, it is most likely allocated during program initialization, thus guaranteeing its presence as soon as it is required, without needing special-case code to detect and perform allocation on access.
The purpose of putting static data into a class is the same as putting any other data into classes. By putting the data into a class structure, you are defining an encapsulating namespace, as well as being able to control access using accessor and mutator methods; this, in turn, will allow you to validate data going into the static memory store, and to ensure consistency throughout the use of this data.
Static variables are stored in a special memory area called BSS, while instances of a class are stored in a heap or on a stack. So, static members are stored separately.
I have one question about static and non-static function and variable.
1) non-static function access static variable.
It's OK!
class Bar
{
public:
static int i;
void nonStaticFunction() {
Bar::i = 10;
}
};
int Bar::i=0;
2) non-static function access non-static variable
Definitely OK!
3) static function access static variable&funciton
Definitely OK!
4) static function access non-static function
It's OK
class Bar
{
public:
static void staticFunction( const Bar & bar)
{
bar.memberFunction();
}
void memberFunction() const
{
}
}
5) static function access non-static variable
It's OK or not OK? I am puzzled about this!
How about this example
class Bar
{
public:
static void staticFunction( Bar & bar)
{
bar.memberFunction();
}
void memberFunction()
{
i = 0;
}
int i;
};
static function access non-static
variable
It's OK or not OK? I am puzzled about
this!
When called, a static function isn't bound to an instance of the class. Class instances (objects) are going to be the entities that hold the "non-static" variables. Therefore, from the static function, you won't be able to access them without actually being passed or storing elsewhere a specific instance to operate on.
So yes, the code in your last example is valid, because you are passed in an instance. However, you could not do:
static void staticFunction()
{
// error, this function is static, and is therefore
// not bound to a specific instance when called
i = 5;
}
Static means this is independent of a particular instance of the class. Static methods don't have access to the this pointer. That is the reason you need to call them using the class name.
When you call the Static method, you might not even have any instance of the class defined.
non-static means implies an instance, and could be different with different instances.
So, basically, it does not make sense to access non-static members from static methods.
For this, you need to understand what is static.
Static data members exist once for the entire class, as opposed to non-static data members, which exist individually in each instance of a class. They will have a class scope and does not bound to an instance of the class.
To access static member of the class, we use the format as below
::
if you have created 10 objects of a class.
Assume, you were able to access the non-static variable in the static member of the class, When the static function is called, which object's member it needs to change?
It's not ok. Static functions are accessible without having an instance of a class and thus can't access information that you would need an instance to determine.
For example, you don't need a car to know how many wheels it has, blueprints for a general car would suffice (that could be static information) but you can't tell what color the car is unless you're referring to a specific car (that information needs a specific instance of an object.)