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.)
Related
I have a class A in which I have a static member function passName
int A::passName()
{
.... // skip some code
std::string name = ...; // result from codes above
assign(); // this is a static member function in class A
pointerA->passMethodName(name); // pointerA is a class-A static member variable, but of type
// class-B, passMethodName is a class-B non-static member function.
}
The assign function is:
void A::assign(){
pointerA = tempPointerA;
}
Explanation: tempPointerA is a value that is generated during the running process. It is a non-static private class-A member which will be initialized everytime a new object of class A is constructed. But I know in static function I can only use static member directly, so I need to make sure that pointerA is static member. So is assign() function feasible (Or I would rather say, is the whole working principle shown here feasible)?
Thanks for your idea!
No. A static member function can only operate on static variables or call other static functions. (or namespace-scope functions, which are more or less the same as static functions).
§9.4.1 [class.static.mfct]
A static member function does not have a this pointer.
So there is no way to access a non-static member variable within a static function.
If you really need assign to remain static, then what you should do is to refactor yourassign()function to accept a variable of typetempPointerA`, and then pass your desired variable in.
int A::passName(B* _in)
{
std::string name = ...; // result from code above
assign(_in); // this is a static member function in class A
_in->passMethodName(name);
}
Otherwise I recommend that you not make it static at all.
Assigning the value will work, but you need to do it from a non-static method (to have access to tempPointerA) or pass the pointer as paramter to the static method. You can access static members from non-static functions (but not the other way around).
What you should pay attention is ownership and destruction. Since you assign the value to a static member the instance can't own the value anymore. Otherwise when the instance is destroyed the static member points to garbage data and you get errors. Also since the static member is never destroyed, your value may leak resources (think DB connection that's never closed).
Also if you are in multi-threaded environment consider if it's possible that multiple threads will attempt to set the value of the static member. You may have the add synchronization. You can also run into race conditions if multiple threads try to initialize the value at the same time.
There is one rule: static functions can't access non-static members and function of the same class without an object. there is no opposite rule. it is because you don't have a this pointer.
You still can declare an object of the same class in the static function and use it's all members, or use any static member.
Therefore from non-static function you can access static functions and members.
If pointerA is static you can access it all. not only to it's static members and functions.
What I have:
So I have a class with a private member, and a static function.
The function must really be static and I can't change that.
What I want:
I need to access, from the static function, the private member.
Any ideas? :)
Please check the code bellow:
class Base
{
private:
int m_member;
public:
Base() : m_member(0) {};
~Base() {};
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); /* This must really be static because it is coming from C */
};
void Base::key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
m_member = 1; // <---- illegal reference to non-static member 'Base::m_member'
}
Static member functions are part of the class, and have no object instance associated with them (in other words, there's no this pointer in static member functions). To be able to access non-static member variables you need an actual instance of the class.
A common solution when setting callbacks using old C libraries, is to use some kind of user-data pointer, and assign it to an instance of the class. Fortunately for you, the GLFW library have such a pointer that you can use.
A static member function cannot access a non-static member (unless it creates its own local instance the non-static member would belong to).
This is because non-static members belong to an instance of the class, and the static member does not. Think about it: If you wrote
Base::callback(...);
what m_member should this access? There simply is no instance of Base and thus not m_member.
You can't. You need an instance to get to the non-static private. In the static method you don't have an instance available.
So you need some way to get an instance, either by passing it to the static method, or by being able to get it from somewhere else. But in that case, you could as well make it a non-static method.
You could make m_member
static int m_member;
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.
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 we have a class as
class Egg
{
static Egg e;
int i;
Egg(int ii):i(ii) {}
Egg(const Egg &); //Prevents copy-constructor to be called
public:
static Egg* instance() {return &e}
};
Egg Egg::e(47);
This code guarantees that we cannot create any object, but could use only the static object. But how could we declare static object of the same class in the class.
And also one thing more since e is a static object, and static objects can call only static member functions, so how could the constructor been called here for static object e, also its constructors are private.
But how could we declare static object of the same class in the class.
A static member variable is not stored inside each object of a class. So if you declare a static member variable inside a class or as a namespace level object after you defined the class, differs only in respect to access (Class::var and var) and access to protected and private members.
And also one thing more since e is a static object, and static objects can call only static member functions
I think you are mixing static functions and static objects. Inside a static function you can call only static functions (unless you are calling them on an object).
so how could the constructor been called here for static object e
Like for every other object a constructor has to be called for static objects, too.
also its constructors are private
Access Control is checked on class level in C++. So since the static object is inside the class, it can access private members.
Unlike in some other languages, the following is legal in C++, since the access to a private member is from inside the class - even if on another object (other in this case):
class Test {
private:
int i;
public:
Test(const Test &other)
: i(other.i)
{}
};
But how could we declare static object of the same class in the class.
Normally you'd need a forward reference, but since Egg e is static, it's actually defined outside of the class definition. If e was not static, you'd get an error (something like "field Egg e has incomplete type").
And also one thing more since e is a static object, and static objects can call only static member functions, so how could the constructor been called here for static object e.
This is not quite true. A static member function within a class can only access static member data. static Egg e is an instance of Egg, so it can access all the members and data a regular Egg can.
also its constructors are private.
Any private member can be used from within a class. Since static Egg e is declared as a member of Egg, it can use the private constructor. The definition of e is outside the class since it's static, but it is still a class member.
And lastly your code doesn't compile because you left out a semicolon here:
static Egg* instance() {return &e;}