C++ static member functions and their scope - c++

I have two questions.
In C++, a static member function has direct access to a public non-static data member defined in the same class?
False
In C++, a non-static member function has direct access to a private static data member defined in the same class?
True
My note say false for the first question and true for the second one. I just cannot find out why? Can you explain why this is? Thank you.
P.S. I'm studying for my final and I cannot seem to figure out why.

Everyone's in agreement, but should be very careful about their wording, because actually static member functions do have access to public non-static data members. For that matter, they have access to private non-static data members too. They just need an object to operate on, to access its members. This could be a parameter, or a global, or created in the static member function, or acquired via one of those things.
The following code is fine:
class foo {
public:
int a;
// static member function "get_a" ...
static int get_a(foo *f) {
// ... accesses public non-static data member "a"
return f->a;
}
};
So we ask ourselves, what's the difference between "access" and "direct access"?
I guess what's meant by "direct access" here must be "using only the name of the data member, without specifying an object". Everyone always needs to have an object in order to access non-static members - that's what non-static means. Non-static member functions just don't have to mention which object if they don't want to, because this is implicit. Hence their access to non-static data members can be direct.
The reason non-static member functions have direct access to private static data members is firstly that the code is in a member of the class, hence it can access private data members. Second, you never need an object in order to access static data members (you can specify one if you want, but all that's used is the static type of the expression, not the actual object), hence the access is direct.

Here's a hint: Recall that a "non-static data member" refers to a data member of a particular instance of your class. A static member function does not run in the context of any particular instance.

Static member functions cannot access instance variables (non-static data), because instance variables need an instance of the class to operate on.
Remember that static data members or functions are defined and allocated once (not per instance), and hence can be accessed by non-static functions just as you would access global variables, etc.
(Internally, static functions don't get passed a this pointer like regular member functions. I.e. they use a different calling convention. Due to this they can't reference this->foo which is what really happens when you reference a member foo in a member function.)

Many object oriented pundits/pandits would tend to silently say, you've got it wrong.
Wrong, not because the answer is wrong but the thinking process needs to be resequenced.
Let's say you are a submarine designer. You have designed the Nehru class submarine. You have the blue prints but not the submarines. On blue print of Nehru class, you have the designer's name - Sonia Gandhi. So now people could STATICally refer to Nehru->designer which yields the value "Sonia Gandhi".
Now, every submarine has a captain. Since no submarine has been built yet, you cannot refer to any captain and therefore the reference Nehru->captain is not logical.
Then you build 10 Nehru class submarines, each assigned a captain. Some of the submarines are the Mumbai, the Delhi, the Rafael Jacob, the Rishi Kapoor.
You still cannot refer to Nehru->captain to get any of the ten captains' names. You could say Delhi->captain, Mumbai->captain or Rishi Kapoor->captain and get the respective captain's name, but there would not be any such valid reference as Nehru->captain because the Nehru reference is a class design and not a ship.
However, you could refer to Delhi->designer or Mumbai->designer or Rafael Jacob->designer which will yield "Sonia Gandhi" just as Nehru->designer would.
There, got it?

In addition to Greg Hewgill's answer, you can think of the static functions as having a more narrow scope - i.e. member functions have access to everything static functions do AND all the instance variables. Static functions though can only access static members, which is logical enough.
class MyClass {
static int m_iStatic;
int m_iInstance;
static void StaticFunc() {
m_iStatic = 8; //OK
m_iInstance = 8; //not OK
}
void InstanceFunc() {
m_iStatic = 8; //OK
m_iInstance = 8; //OK
}
}

In C++, a static member function has
direct access to a public non-static
data member defined in the same class?
False
Static member functions cannot access non-static data of the class due to the fact that static member function is not bound to the instance. For that matter static function can be accessed without any object. Any object specific data cannot be accessed in static member function.
In C++, a non-static member function
has direct access to a private static
data member defined in the same class?
True
Again, since static data member does not belong to any particular object it can be accessed by all instances of the class.

to make things easier, lets strip the public/private away.
To access data member (attribute) of an object, you will need to know who/where is the 'object'.
A static member function are shared across among objectS so it will need additional information when you ask him to grab the data member.
image object as family, child is the data member, boardSchoolBus is the static function.
every children can board the school bus, but if you asked school bus to fetch a child, it would need to know which family to go right?

Related

Can static functions be virtual in C++?

I found some statements regarding my above question, but there are diferent claims:
The static member function can't access non-static data members/functions of a class. The vPTR is non-static data member, hence a static member function can't access vPTR.
No, because it doesn't make any sense in C++.
Virtual functions are invoked when you have a pointer/reference to an instance of a class. Static functions aren't tied to a particular instance, they're tied to a class. C++ doesn't have pointers-to-class, so there is no scenario in which you could invoke a static function virtually.
Which is one is right and for what reason?
No, static functions cannot be virtual in C++.
It would occasionally be useful if the function does not depend on any members of the class but is, in a sense, dependent on the type:
struct Animal
{
static virtual std::string whatNoiseDoIMake() = 0;
};
struct Dog : Animal
{
static std::string whatNoiseDoIMake()
{
return "woof"s;
}
};
The reason it's not part of the language are due to it not being proposed to and accepted by the C++ standards committee. My example can be solved using type traits, which weakens the case for such constructs to be allowed.
As for const, that really is about the possibility of modifying non-mutable class members. It's harder to concoct a meaningful example of a const static member function. Perhaps it could apply to static members, but then such members are reachable via :: anyway with (interestingly) access specifiers discarded.
Which is right one and for what is the exact reason?
The static member function can't access non-static data members/functions of a class. The vPTR is non-static data member, hence a static member function can't access vPTR.
No, because it doesn't make any sense in C++.
Virtual functions are invoked when you have a pointer/reference to an instance of a class. Static functions aren't tied to a particular instance, they're tied to a class. C++ doesn't have pointers-to-class, so there is no scenario in which you could invoke a static function virtually.
The first statement is correct, in the sense that static member functions do not have access to the *this pointer, they have a class scope. A static member is shared by all instances of the class.
In the second statement the first part is opinion-based, one can argue that it could be useful, as #Bathsheba points out. The second part is correct.
Regardless of the possible sense or merit of the use of such construct, the standard is clear as to why virtual static member functions are not allowed:
11.7.2 Virtual functions [class.virtual#11]
[ Note: The virtual specifier implies membership, so a virtual function cannot be a non-member ([dcl.fct.spec]) function.
Nor can a virtual function be a static member, since a virtual function call relies on a specific object for determining which function to invoke.
A virtual function declared in one class can be declared a friend ([class.friend]) in another class.
— end note
]
No, they can't.
Virtual members were designed to deal with instances of the class.
Static members do not deal with instances, they relate only to class.
How would you select which "virtual static" function to call depending on instance (as in dynamic polymorphism) as there is no connection to any instance?
These are just two different mechanism that have mutually excluding dependencies.
Can static functions be virtual in C++?
No.
The static member function can't access non-static data members/functions of a class.
That isn't quite right: static methods can absolutely access non-static (instance) members ... if you give them an instance. They have access, they just don't have a default this object to operate on.
The vPTR is non-static data member, hence a static member function can't access vPTR
We don't need to dwell on implementation details such as vtables. It's sufficient to say that virtual dispatch depends on the dynamic type of an object, and if you don't have an object, there's no type ambiguity that could possibly benefit from virtual dispatch.
C++ doesn't have pointers-to-class, so there is no scenario in which you could invoke a static function virtually
Note that in languages with this facility, you still don't need a special system for static virtuals - it's generally just that classes are objects. So in that case, static methods of a regular class are still instance methods of the class object.
The first statement assumes a "vptr". That refers to a common implementation technique in C++ compilers, where each object with virtual functions contains a hidden pointer to some "vtable", which in turn contains pointers to the virtual functions.
This is however an implementation detail of those compilers. They've chosen that implementation because it's a possible implementation, allowed by the C++ standard.
One of the reasons it's allowed is because the C++ standard says that you always need an object to call a virtual function on, so there's always an object to store that "vptr" in.
The first answer therefore confuses cause and effect. Implementations can use a "vptr" because virtual functions need an object and therefore can't be static, not the other way around.
Static Functions can not be virtual in c++ since the concept leads to compile error and is basically resolved at run time

Calling member function without creating object in C++

Can anyone explain why we can call static member functions without creating instance of an object but we can't in case of non-static functions?
I searched everywhere, I couldn't find an explanation, Can you help?
You've got the logic basically in reverse. It is useful to have functions that belong to a class, even though they do not need to be called on an object of that class. Stroustrup didn't want to add a new keyword for that, so he repurposed the existing keyword static to distinguish such methods from normal methods.
In hindsight, other options could have been chosen. We could have made this an explicit function argument for the normal methods, for instance. But that's about 30 years too late now.
Why?
Because we like encapsulation and modularity which we get when using object orientated patterns.
You can view static class member functions and variables as a way of encapsulating what would otherwise have been global functions and variables - which might collide.
Underneath, there is not a great deal of difference between a plain old C++ file with some functions declared and implemented in it, to a class filled with only static functions. The difference is we can cleanly access a set of functions attached to a parent class.
An example:
Suppose you want to create a new class like MyMediumInteger, and you want developers to determine what the maximum number it can hold is. This information is applicable for every instance of MyMediumInteger, no matter what the state of the private member variables are. Therefore it makes sense to expose this information without forcing the developer to instantiate the class. Your options include defining something global such as #define MYMEDIUMINTEGER_MAX ... which could collide with a define sharing the same name in another module, or create a static function returning the max size, called neatly via
MyMediumInteger::maxSize().
A code example:
/***
* Use a static class member function (or variable)
*/
class MyMediumInteger
{
public:
static unsigned long maxSize() { return pow(2, 32) - 1; };
};
auto maxSize = MyMediumInteger::maxSize();
/**
* Alternative approaches.
* Note: These could all collide with other #defines or symbols declared/implemented in other modules.
* Note: These are both independant sources of information related to a class - wouldn't it be nicer if they could just belong to the class instead?
*/
/***
* Use a #define
*/
#define MYMEDIUMINTEGER_MAX (pow(2, 32) - 1)
auto maxSize = MYMEDIUMINTEGER_MAX;
/**
* Use a global function or variable
*/
static unsigned long getMyMediumIntegerMaxSize()
{
return pow(2, 32) - 1;
}
auto maxSize = getMyMediumIntegerMaxSize();
A word of warning:
Static member variables and functions have some of the pitfalls of global variables - because they persist through instances of classes, calling and assigning to them can cause unexpected side effects (because static member variables get changed for everyone, not just you).
A common pitfall is to add lots of static member functions and variables for management - for example, maintaining a list of all other class instances statically which gets appended to in the constructor of each class. Often this type of code could be refactored into a parent class whose job it is just to manage instances of the child class. The latter approach is far more testable and keeps things modular - for example, someone else could come along and write a different implementation of the management code without appending to or re-writing your child class implementation.
How?
In C++ class member functions are not actually stored in class instances, they are stored separately and called on instances of classes. Therefore, it's not hard to imagine how static functions fit into this - they are declared in the same way as normal class member functions, just with the static keyword to say "I don't need to be given a class instance to be run on". The consequence of this is it can't access class member variables or methods.
Static member functions does not need a "this" pointer, it belongs to the class.
Non-static functions need a "this" pointer to point out in which object it belong to, so you need to creat a object firstly.
Because that's what static means: "I don't want this function to require an object to work on".
That's the feature. That's its definition.
Any other answer would be circular.
Why is it useful? Sometimes we want to be able to "organise" some data or utilities in our classes, perhaps for use by external code or perhaps for use by non-static functions of the same class. In that sense there is some crossover with namespaces.

private static member function vs private member function

One can choose public static over private static if the static needs to be accessed outside the class(e.g. singleton), while private static is preferred when the function need not be exposed(otherwise unnamed namespaces would do fine) - in which case its only access either through static member function or other non static member functions
However i am trying to get to the core idea of why would one choose private static over private member function?
Ofcourse, both can have access to private members of the class(or any object that is passed), with static member explicitly requiring an object to be passed, but why can't i keep my design open by making it a private Non-Static member function even if it doesn't need access to private members(just like static member functions). This way even if in future i require to access some private members i save myself from converting static to non-static mem func - I understand this isn't a big deal/change but still can somebody give me a crystal clear idea about when and why to choose one over the other?
When you have a static member variable, you choose its access level in just the same way that you would for a non-static member variable. There's nothing "special" here.
Most of my private statics tend to be things like built-in constants that are only used by the internals of the class.
I admit I can't think of many other use cases for them, but I will also tend to make any function static if it logically has nothing to do with a particular instance of the class (and thus needs no non-static member access) — this may be a bit more OCD than some people indulge in though.
why can't i keep my design open by making it a private Non-Static member function even if it doesn't need access to private members(just like static member functions)
You can. It is up to you.
This way even if in future i require to access some private members i save myself from converting static to non-static mem func
Sure. I mean, it's one keyword. But this "forward-compatibility" may be useful if you need to keep your headers from changing (e.g. you're deploying them). Arguably this is a downside of making static members private, where there aren't really many solid upsides. Again, it's up to you.

Unnamed namespaces vs private variables

I have been reading through other questions on here and there is something that has me confused and hopefully it can be explained. I am sure there it is a simple thing but it is alluding me.
So in C++ we have private variables that are only viewable within the class:
class MyClass
{
private:
int i;
};
But we can also have unnamed namespaces:
namespace
{
int i;
}
Both appear to be private to the class but in the 2nd case you cannot see they exist from the header file. From reading other questions it seems that functions are different as you can't pass class objects to them? But I am not sure what the difference is here for variables.
Is there a disadvantage to the 2nd way that means you should still use private variables?
They aren't the same.
Integer i in the anonymous namespace will be shared by all instances of MyClass.
The private integer i in MyClass will be unique for each instantiation of the class.
The equivalent using private would be to make i static:
//.h
class MyClass
{
private:
static int i;
};
And instantiate the one single shared i like this:
//.cpp
int MyClass::i = 0;
Both appear to be private to the class ...
No, only the first is private to the class. It's a non-static member variable; one is instantiated in every object of the class type.
The second is not in a class at all; it has static storage duration, so one is instantiated for the whole program. Anything that accesses it is accessing the same variable as anything else that accesses it. Being in an unnamed namespace, it's only accessible within the translation unit (i.e. the source file) that defines it; but it's accessible to any code there, not just a particular class.
Is there a disadvantage to the 2nd way that means you should still use private variables?
If you want a copy of the variable in each class object, then you need it to be a non-static member.
If you want to share it between all objects, then it's up to you whether to make it a static member, or put it in a namespace inside the class's implementation file. I often do the latter to simplify the class definition. Disadvantages are that access isn't restricted just to the class but to anything else in that file, and you can't access it from any code that you might want to put in the header.
Namespaces are unrelated to objects/classes. In particular, if you have two objects, each has its own copy of a private variable.
They are quite different concepts. The private data member is visible only to a class, and in the non-static case, each class instance owns one of these. The anonymous namespace allows you to make code available only to other code in the same file. So in the case of the single int variable, all code defined in the same place as the anonymous namespace would see the same, single variable.

How to properly pass the value of a static member variable?

In C++, I have a static member variable in a class.
Then I pass this static member variable to a array of struct initialization. Now my problem is the value of that member in struct is gone.
Please explain if I'm missing some understanding about a static member variable. Did a static member have a limitation of passing its own value?
Please advice.
Many thanks
A static member variable is like a regular global except that:
Its name is scoped to that of the class in which it is a member. The class acts like a namespace, but in a more powerful way as it can be used in templates.
It can be protected or private in which case only those that have access to the class can access the member.
There is one instance of this, not one per object.
Private static member variables can usually be replaced with a "hidden" variable of the same type in the anonymous names of the compilation unit for the class. This is a preferable option as you then do not need to expose the implementation of your class (which is what private members usually are) in the header.
It would be useful to give an example that duplicates your error so we can see exactly what you are trying to do and why it does not work.