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
Related
Invoking a protected constructor in a derived class is not allowed, as explained here.
The accepted answer explains that protected grants access to members of an object of base class A only when that object of class A is a subobject of class B. So far, so good.
But then, why is it allowed (at least in GCC 4.6.3) to call static protected methods? Specifically, it doesn't make any sense to me that the following compiles, while the commented line does not:
class A
{
protected:
A() {}
static A makeA() { return A(); }
};
class B: public A
{
public:
static A makeAFromB()
{
return makeA(); // compiles
// return A(); // does not compile
}
};
Philosophically, a constructor is pretty much like a static method returning an object of class A, reason why I don't get the difference in behaviour here.
But then, why is it allowed (at least in GCC 4.6.3) to call static protected methods?
Because that's what the Standard says. The constraints that apply to the accessibility of protected members (and that the answer you linked explains very well) are defined in paragraph 11.4/1 of the C++11 Standard, whose first sentence specifies:
An additional access check beyond those described earlier in Clause 11 is applied when a non-static data
member or non-static member function is a protected member of its naming class (11.2). [...]
The additional access check does not apply to static members or static member functions.
You're right that the way protected only grants access to the embedded base object can be surprising... but there's a good reason for it. Say you have a couple classes derived from Base, and a method in one of those classes wanted to do things to an arbitrary Base object via some reference or pointer... it might be that the Base it's fiddling with is part of the other derivation chain, which has other behavioural expectations of the Base object given the usage it makes of the protected member functions. You're effectively removing the encapsulation that the other derived class intended, preventing it enforcing intended invariants, stepping outside the world of good OO behaviours.... Applying this insight to your specific scenario, the C++ rules are preventing you using that protected constructor to make a subobject that was expected to have invariants policed by some derived class, when there is actually no derived object into which that Base object will be embedded.
Separately, the way protected works for constructors has clear utility - it prevents construction of the class (using that constructor) except as a subobject of the derived class, or from member functions of the base class (such as makeA in your example) - whether they're static or non-static member functions is irrelevant... all member functions always have full to the class.
What would be the utility in ignoring the intuitive meanings of private/protected/public for static member functions? You're saying you expect them to be effectively private, if that's behaviour you want then just make them private / if you need them accessible leave them protected. Clearly the protected access is limited as per the justification in my first paragraph.
Static methods are inherited in the sense that they're available amongst the child class's methods. We can call a static method using the child class's name, or using an instance of the child class, or without qualification in the body of a child class.
Does every class have virtual function table in C++?
I know virtual table is for polymorphism. Class with virtual functions must have v-table. But how about class has no virtual function? Or how about class has no base class?
The language specification of C++ does not define what a "vtable" is, or which classes need one.
A particular implementation of C++ in a compiler often uses a vtable to implement virtual methods. If a class has no virtual methods (and no superclasses with virtual methods), then the compiler may omit the vtable. However, keep in mind this is purely a compiler implementation decision, and not required by the standard.
As a non-standard rule of thumb (vtables are not dictated by the standard) which applies to virtually all compilers:
Only classes with virtual member functions and/or a virtual destructor have a vtable. Other classes not. This conforms to the general rule in C++ "pay for what you use".
Of course this puts you into an important responsibility: Is your class to be deleted polymorphically? I.e., will it be used as a public base class and be deleted through it? Then make the destructor virtual.
C++ language as such doesn't talk about how virtual functions needs to be implemented i.e. it can using vtables or any other mechanism. Having said that, generally it is implemented using v-table, and this v-table is created only if the class contains virtual functions.
v-table holds the function's address in it. This table will hold the function address of all the virtual functions that are defined in the base class.
Based on the actual object type, this address changes and the exact function is called.
If the class does not inherits any of the class with virtual function, it need not hold any v-table. All the functions calls will be linked compile time.
Because of C++ nature of static-binding for methods, this affects the polymorphic calls.
From Wikipedia:
Although the overhead involved in this dispatch mechanism is low, it
may still be significant for some application areas that the language
was designed to target. For this reason, Bjarne Stroustrup, the
designer of C++, elected to make dynamic dispatch optional and
non-default. Only functions declared with the virtual keyword will be
dispatched based on the runtime type of the object; other functions
will be dispatched based on the object's static type.
So the code:
Polygon* p = new Triangle;
p->area();
provided that area() is a non-virtual function in Parent class that is overridden in the Child class, the code above will call the Parent's class method which might not be expected by the developer. (thanks to the static-binding I've introduced)
So, If I want to write a class to be used by others (e.g library), should I make all my functions to be virtual for the such previous code to run as expected?
The simple answer is if you intend functions of your class to be overridden for runtime polymorphism you should mark them as virtual, and not if you don't intend so.
Don't mark your functions virtual just because you feel it imparts additional flexibility, rather think of your design and purpose of exposing an interface. For ex: If your class is not designed to be inherited then making your member functions virtual will be misleading. A good example of this is Standard Library containers,which are not meant to be inherited and hence they do not have virtual destructors.
There are n no of reasons why not to mark all your member functions virtual, to quote some performance penalties, non-POD class type and so on, but if you really intent that your class is intended for run time overidding then that is the purpose of it and its about and over the so-called deficiencies.
Mark it virtual if derived classes should be able to override that method. It's as simple as that.
In terms of memory performance, you get a virtual pointer table if anything is virtual, so one way to look at it is "please one, please all". Otherwise, as the others say, mark them as virtual if you want them to be overridable such that calling that method on a base class means that the specialized versions are run.
As a general rule, you should only mark a function virtual if the class is explicitly designed to be used as a base class, and that function is designed to be overridden. In practice, most virtual functions will be pure virtual in the base class. And except in cases of call inversion, where you explicitly don't provide a contract for the overriding function, virtual functions should be private (or at the most protected), and wrapped with non-virtual functions enforcing the contract.
That's basically the idea ; actually if you are using a parent class, I don't think you'll need to override every methods so just make them virtual if you think you'll use it this way.
Suppose I have a purely virtual class, can I do something like this in C++:
class ITreatable
{
public:
bool hasBeenTreated; // <- Can this be here?
virtual bool Treat() = 0;
};
And if not, how can I ensure that classes which inherit ITreatable have a member variable called hasBeenTreated? Is that possible? Is there some kind of best practice that avoid having to do this / advises against it?
Thanks
Edit: Also how would I define a constructor for such a class?
Edit2: I understand that public member variables are bad practice, I'm just wondering if the design in general is a good idea in C++ or not.
Absolutely.
Strictly speaking, there is no such thing as a "virtual class". I understand that you are using the term to mean a class constructed of only data members and virtual member functions.
Consider that only functions can be virtual; if you wish for data members to be accessed polymorphically, you must do this through functions. Thus, use virtual getter/setter functions, and keep your data members private.
Acordingly to MSDN an interface has these characteristics:
An interface class (or struct) must be declared within a namespace
and may have public or private accessibility. Only public interfaces
are emitted to metadata.
The members of an interface can include properties, methods, and
events.
All interface members are implicitly public and virtual.
Fields and static members are not permitted.
Types that are used as properties, method parameters, or return
values can only be Windows Runtime types; this includes the
fundamental types and enum class types.
So I would response to your question with
NO if you want an interface
and
Yes if you just use abstract classes, but as the others say, make them private and use public getters and setters
Yes.
There is no concept of a "pure virtual" class in C++, merely abstract classes with virtual members.
As for whether there is a best practice, I would say that the biggest practice that should be followed in this example is not to use public variables. Rather, have a setter/getter defined in the base class that modifies a private variable.
That is possible. C++ doesn't have interfaces enforced by the language, so your example acts like normal class definition without any special rules.
It's considered bad practice to declare variables as public in classes. You might want to make it private and declare accessor/mutator for it or declare it as protected.
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?