Pointers to static members of class - c++

From this reference:
(8.3.3/3) A pointer to member shall not point to a static member of a
class (9.4), a member with reference type, or "cv void."
Why a pointer cannot point to a static member of a class?
struct S {
static int f() { /*...*/ };
};
int main()
{
int (S::*s)() = &S::f; // why?
}

Why a pointer cannot point to a static member of a class?
Because for the purpose of membership it isn’t a member, merely for the purpose of scope. Apart from scope, static members are just like free functions, unattached to an instance of a class. You can use non-member function pointers:
int (*s)() = &S::f;

Whenever you do T::*, you're saying "this thing requires an instance of T to use." That statement does not hold for static functions, which are callable without any instances of the class.

You'd have to use a regular function pointer, like so:
int (*s)()=&S::f;
Like GMan said, static methods don't work on instances, so they don't receive the hidden this pointer. This effectively makes them have a different signature from instance methods with the same arguments.

Related

Pointer? Pointer Function?

i recently started coding and I've been trying to figure out what this means for a while:
static thing* dostuff();
thing* thing::dostuff(){};
I searched function pointers but they look different. These types of functions seem to come up in important areas of code and I'd like to know what they mean and how to use them. thanks you.
Your code fragments static thing* dostuff() and thing* thing::dostuff(){} have nothing to do with function pointers, but are the declaration of a function and the definition/implementation of this function.
static thing* dostuff(); declares a function that returns a pointer of data type thing, which is probably a class type.
So it's very likely that dostuff is actually a member function defined in a class thing. Keyword static declares members that are not bound to class instances, and static member functions are not associated with any object. When called, they have no this-pointer:
class thing {
static thing* dostuff();
};
Then, thing* thing::dostuff(){} is the implementation of this static member function of class thing. Prefix thing:: denotes that this function is part of class thing.
It's just a static member function of thing, called dostuff, returning a pointer of type thing*.
There's nothing special or weird about it.

Private/public static member function

I was reading before that static member functions of a class is similar to a global function. But this should depend on whether or not the static member function is public/private right?
For example:
class A
{
private:
static void aFunc();
};
int main()
{
A::aFunc();
}
In this case I wouldn't be able to call the static member function inside main() correct? If I instead had made it public, I can call it, just like a global function?
Yes, it does depend on the access modifier. If the function is public, then it is somewhat similar to a global function, but unlike a global function it has access to class members and has to be called with the class scope (prefixed with A:: in your example), to mention just a couple of differences.
BTW, when you call it in main(), you should just have
A::aFunc()
No need to stick void in there.
Yes, a static member function is similar to a non-member function in that you do not need to call it for an object of associated class type, but it obeys the usual class member access rules like a non-static member function.
In this case, you are correct to suggest that A::aFunc is inaccessible from main. However, your calling syntax is incorrect. You do not need to include the return type:
A::aFunc();

C++: Can I assign the value of non-static member variable to static member variable?

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.

Working example of accessing non-static member from static method

I was studying ns-3 tutorial. I cannot understand the following code snippet:
class MyObject : public Object
{
public:
static TypeId GetTypeId (void)
{
static TypeId tid = TypeId ("MyObject")
.SetParent (Object::GetTypeId ())
.AddConstructor<MyObject> ()
.AddTraceSource ("MyInteger",
"An integer value to trace.",
MakeTraceSourceAccessor (&MyObject::m_myInt))
;
return tid;
}
MyObject () {}
TracedValue<int32_t> m_myInt;
};
As I understand, MyObject::m_myInt is an access to non-static class member m_myInt from static method and & takes address of this member. This code is successfully compiled and executed. How can it be possible? What instance of class does the static method use?
Pointers to members can be pointers to either member methods or member variables and do not need an instance of a class to be declared or assigned. This does not mean you can do much without an instance, however. You still need an instance to use them. Consider the following code:
class A
{
public:
void SomeMethod();
int someVar;
};
void (A::*pSomeMethod)() = &A::SomeMethod; //Declares a member pointer to method and assigns
int A::*pSomeVar = &A::someVar; //Declares a member pointer to int variable and assigns
A a; //Defines an instance
(a.*pSomeMethod)(); //Uses an instance with the pSomeMethod member pointer.
int var = (a.*pSomeVar); //Uses an instance with the pSomeVar member pointer.
It is possible, and it allows for some pretty cool stuff.

non-static vs. static function and variable

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.)