Devirtualise Child Class Call - c++

Let's say I have a Parent class that implements a virtual method, overridden by a Child class. I understand that if the method is called on a variable of type Parent then the compiler must use some way of checking which implementation of the method should be called at run time, but surely this is not necessary if the variable is of type Child? In this case, assuming that the method is not overridden again by a child of Child, will the compiler devirtualise the method since it is known that the variable will definitely contain a Child, and is this compiler specific?

In order to de-virtualize a call, the compiler would have to know for certain that there are no derived types of Child that it might be passing through the code with:
void f(Child* c) {
Child* l = new Child;
c->virtFn();
l->virtFn();
}
The c call to virtFn could be for a derived type, but the l call can't.
C++11 introduced the final keyword that can assist with this and allow the compiler to devirtualize calls through a terminal class pointer/ref.

Related

How does C++ knows child class calls a parent method?

I don't know how to summarize my question so couldn't find an answer on Google.
When overriding a parent method,
void Child::method(){
//stuff
Parent::method();
}
Works perfectly. But the parent method requires the information from the Child class instance to work properly, which is not given as arguments. So my question is, does C++ have a mechanism to let the Parent know which instance of a Child class calls a Parent method, like without doing Parent::method(this) ?
The thing that makes me think this is, if you do something like this,
int main(){
SomeParentClass::someMethod();
}
It gives: error: call to non-static member function without an object argument. So the compiler needs to know the instance, which was not also given in the child class. But did not raise an error so it must have known the instance.
Edit: I added the Qt tag because I am experimenting on a Qt class. So that I can give an example if needed.
Edit2:
devicedialog.h
class DeviceDialog : public QDialog
{
Q_OBJECT
public:
explicit DeviceDialog(QWidget *parent = nullptr);
int exec() override;
~DeviceDialog() override;
}
devicedialog.cpp
int DeviceDialog::exec(){
// My code.
return QDialog::exec();
}
exec() function activates and shows a QDialog on the screen. However, that way it is called, it seems like the parent method has no way of knowing which dialog to show (no parameters passed). The only knowledge could be the identity of the instance calling it. I am just asking if this knowledge transferred to the method in the background.
I think you are just being confused by the language's attempt to make things easier on you. Your example function is equivalent to
void Child::method(){
//stuff
this->Parent::method();
}
Just as you cannot call a (non-static) method in the child class without an object, you cannot call the parent's method without an object. However, the context is the body of such a method. Within the body, the context is assumed to be *this. Just as you can refer to data members without explicitly prefixing "this->", you can call methods without the prefix.
This is nothing special to member functions of a parent class. Calling a function of the child class via explicitly naming the type:
Child::method();
works in exactly the same way in this regard. Used outside of a member functions definition it causes the same error.
The relevant paragraph of the standard is ยง9.3.1:
When an id-expression that is not part of a class member access syntax
and not used to form a pointer to member is used in a member of class
X in a context where this can be used, if name lookup resolves the
name in the id-expression to a non-static non-type member of some
class C, and if either the id-expression is potentially evaluated or C
is X or a base class of X, the id-expression is transformed into a
class member access expression using (*this) as the postfix-expression
to the left of the . operator.
So, in other words, the call
Parent::method();
inside a member function is transformed into something akin to
(*this).Parent::method();
This is still a c++ specific question. Qt just utilizes it. You need to study objects, inheritance, and virtual methods.
void Child::method() {
Parent::method();
// this->Parent::method();
}
The above works because the child has access to the parents methods (that are not private). Because the method is an override of the parents virtual method, the only way for the compiler to know you want to call the parents method is to call it with scope resolution '::' in the child.
int main() {
SomeParentClass::someMethod();
}
The above does not work because there is no instantiated object. When you call a method, you call it on the object (unless it is a static method). So instead you would do something like:
int main() {
SomeParentClass parent;
parent.someMethod();
ChildClass child;
child.someMethod(); // accesses the childs overridden method and not the parents.
}

Why do we need a pointer of superclass to point to a object of a subclass?

I'm learning C++ now and I read a lot of materials about using superclass's pointer to point to a subclass' object, especially in the case of (pure) virtual classes. Since I don't have a lot of experience, could anyone help me to understand why we need to do that? Thanks a lot!
You don't need to. You can use a pointer to the derived type if that's what you really want.
The Liskov substitution principle says that we should always be able to use a derived type wherever the base type is expected. The idea is that a derived type should be no more restrictive than its base class. That way, the derived really is-a base type, and can be used wherever the base type would be used. The base type defines the interface and the derived type should meet that same interface. The derived type can augment the interface, if it likes.
The type of pointer that your function should take depends on exactly what you want to be able to accept. If you have a hierarchy with two Widgets, Button and List, for example, then if your function is happy to take any kind of Widget, it should take a Widget*. If the function specifically requires a Button, however, it should take a Button*. The reason for this is that the function probably requires some functionality that only the Button can provide.
When a member function is called through a pointer and the compiler sees that that function is virtual, the compiler ensures that the dynamic type of the object is used to determine which function to call. That is, imagine you have a Widget* parameter but actually pass a pointer to a Button object. The static type of the object is Widget (if the compiler were to only look at the parameter type), but its dynamic type is Button. If you call widget->draw(), where draw is a virtual function, it will see that the dynamic type is Button and ensure that Button::draw is called.
However, I don't recommend using raw pointers in general, so prefer references (Widget&) or smart pointers if you can.
Here's an example:
struct base { virtual void do_stuff(); = 0 };
struct specialization1: base {
void do_stuff() override { std::cout << "doing concrete stuff"; }
};
Consider that you have client code that wants to call do_stuff.
First implementation (this is how not to do it):
void client_do_stuff( specialization1& s ) { s.do_stuff(); }
This function works. If you decide (four months from now) to add to your code base:
struct specialization2: base {
void do_stuff() override { std::cout << "doing other concrete stuff"; }
};
You may want to call void client_do_stuff for an instance of specialization2. You could duplicate client_do_stuff with a specialization2 reference, but that is code duplication and unnecessary.
A better solution would be to change client_do_stuff to take a reference to the base class, and use the same implementation with both specializations.
Second implementation:
void client_do_stuff( base& b ) { b.do_stuff(); }
client code:
specialization1 s1;
specialization2 s2;
client_do_stuff(s1); // works
client_do_stuff(s2); // works
This implementation of client_do_stuff is implemented in terms of the public interface of the base class, instead of a specialization. This makes the function "future-proof" (the principle is sometimes called "program to an interface, not an implementation").
The idea is as follows: An object has the following interface (the pure virtual class). I will hand a concrete object to your code, which adheres to this interface, but the internal details of said object I will keep to myself (encapsulation). Thus your code can make no assumptions on the precise size etc. of the object. Therefore when compiling your code, you have to use pointers or references when manipulating the object.

Virtual methods in constructor

Calling virtual methods in C++ is prohibited, however there are a few situations, where it might be very useful.
Consider the following situation - pair of Parent and Child classes. Parent constructor requires a Child class to be instantiated, because it has to initialize it in a special way. Both Parent and Child may be derived, such that DerivedParent uses DerivedChild.
There's a problem, however - because in Parent::ctor call from DerivedParent::ctor, base class should have an instance of DerivedChild instead of Child. But that would require calling a virtual method some way, what is prohibited. I'm talking about something like this:
class Child
{
public:
virtual std::string ToString() { return "Child"; }
};
class DerivedChild : public Child
{
public:
std::string ToString() { return "DerivedChild"; }
};
class Parent
{
protected:
Child * child;
virtual Child * CreateChild() { return new Child(); }
public:
Parent() { child = CreateChild(); }
Child * GetChild() { return child; }
};
class DerivedParent : public Parent
{
protected:
Child * CreateChild() { return new DerivedChild(); }
};
int main(int argc, char * argv[])
{
DerivedParent parent;
printf("%s\n", parent.GetChild()->ToString().c_str());
getchar();
return 0;
}
Let's get a real-world example. Suppose, that I want to write wrapper for WinApi's windows. The base Control class should register class and instantiate a window (eg. RegisterClassEx and CreateWindowEx), to properly set it up (for example register class in such way, that window structure has additional data for class instance; set up generic WndProc for all Controls; put reference to this by SetWindowLongPtr etc.)
On the other hand, derived class should be able to specify styles and extended styles, class name for window etc.
If constructing instance of window in the Control's constructor is a contract to be fulfilled, I see no other solution than to use VMs in ctor (what won't work).
Possible workarounds:
Use static polymorphism (eg. class Derived : public Base), but it will not work, if one wants to derive from Derived;
Pass a lambda from derived to base ctor if it is possible - it will work, but it's a total hardcore solution;
Pass a ton of parameters from derived to base ctor - it shall work, but won't be neither elegant, nor easy to use.
I personally don't like neither of them. Out of curiosity, I checked, how the problem is solved in Delphi's VCL, and you know what, base class calls CreateParams, which is virtual (Delphi allows such calls and guarantees, that they are safe - class fields are initialized to 0 upon creating).
How can one overcome this language restriction?
Edit: In response to answers:
Call CreateChild from the derived constructor. You're already requiring CreateChild to be defined, so this is an incremental step. You can add a protected: void init() function in the base class to keep such initialization encapsulated.
It will work, but it's not an option - quoting the famous C++ FAQ:
The first variation is simplest initially, though the code that actually wants to create objects requires a tiny bit of programmer self-discipline, which in practice means you're doomed. Seriously, if there are only one or two places that actually create objects of this hierarchy, the programmer self-discipline is quite localized and shouldn't cause problems.
Use CRTP. Make the base class a template, have the child supply the DerivedType, and call the constructor that way. This kind of design can sometimes eliminate virtual functions completely.
It's not an option, because it will work only once, for base class and its immediate descendant.
Make the child pointer a constructor argument, for example to a factory function.
This is, so far, the best solution - injecting code into base ctor. In my case, I won't even need to do it, because I can just parametrize base ctor and pass values from the descendant. But it will actually work.
Use a factory function template to generate the child pointer of the appropriate type before returning a parent. This eliminates the complexity of a class template. Use a type traits pattern to group child and parent classes.
Yea, but it has some drawbacks:
Someone, who derives from my classes may publish his ctor and bypass the security measures;
It would prevent one from using references, one would have to use smart pointers.
Calling virtual methods in C++ is prohibited, however there are a few situations, where it might be very useful.
No, calling a virtual method in the constructor dispatches to the most-derived complete object, which is the one under construction. It's not prohibited, it's well-defined and it does the only thing that would make sense.
A C++ base class is not allowed to know the identity of the most derived object, for better or worse. Under the model, the derived object doesn't start to exist until after the base constructors have run, so there's nothing to get type information about.
Some alternatives in your case are:
Call CreateChild from the derived constructor. You're already requiring CreateChild to be defined, so this is an incremental step. You can add a protected: void init() function in the base class to keep such initialization encapsulated.
Use CRTP. Make the base class a template, have the child supply the DerivedType, and call the constructor that way. This kind of design can sometimes eliminate virtual functions completely.
Make the child pointer a constructor argument, for example to a factory function.
Use a factory function template to generate the child pointer of the appropriate type before returning a parent. This eliminates the complexity of a class template. Use a type traits pattern to group child and parent classes.

Is it possible to override a function in C++ child class without using virtual keyword to the function in parent class which is abstract?

class Parent {
public:
void func1(); // Complete meaningful definition in parent given.
virtual HRESULT func2()=0; // Bcoz of this function Parent class is abstract.
};
class Child: public Parent {
public:
void func1(); // Different definition in child.
};
Is this possible in C++ ? I am overriding func1() which is NOT virtual and it already has a definition in parent abstract class.
[assuming here Child extends Parent, unlike what the code snap shows]
Yes it is possible [it is called hiding] - but you will not get a dynamic dispatch behavior.
The static type will define which method will be invoked, and not the dynamic type.
For example:
Parent* p = new Child;
p->func1();
Will invoke Parent::func1()
while:
Child* c = new Child;
c->func1();
Will invoke Child::func1()
No, it's not possible to actually override the definition in the parent (at least when talking about C++, "override" is normally reserved specifically to referring to virtual functions). Instead, defining a function with the same name in the child class simply hides the function in the parent that has the same name (i.e., in the context of a child object, looking for that name will only find the function in the child, not the one in the parent).
If you want to (and the functions have different signatures) you can also get the functions in both the parent and the child treated as overloaded, so a call will try to call whichever matches better:
struct parent {
void func1(char) {}
};
struct child : public parent {
void func1(long) { }
using parent::func1;
};
Now, you get:
child c;
c.func1('a'); // calls parent::func1
c.func1(123L); // calls child::func1
This is yet a third type of behavior though, different from having a virtual function or having a function in the child that hides the one in the parent.
With a virtual function, the selection of which function is called is based on the dynamic type, so if you have a pointer/reference to the base class, the function called depends on whether that refers to an object of the base or derived class.
When you hide the function, the function that's called is based on the static type, so if you call it via a pointer/reference to the base, it calls the base function, even if that actually refers to an object of the derived class. If, however, you use a pointer or reference to (or directly use an instance of) the derived class, it'll invoke the function in the derived class.
With the using statement, you get function overloading, so when you call the function (in the context of the derived class) the function that's called is based on which function's signature is the best match for the parameter(s) you pass.
You can overload it, if they have distinct argument types.
You can hide it, in the sense shown here, so that Child::func1 will be called instead of Parent::func1 in code that knows it's looking at a child instance. However, as amit points out, you don't get dynamic dispatch.
struct StaticParent {
void foo();
};
struct StaticChild : public StaticParent {
void foo();
}
StaticChild sc;
sc.foo(); // calls StaticChild::foo
StaticParent &sp = sc;
sp.foo(); // calls StaticParent::foo
struct VirtualParent {
virtual void foo();
};
struct VirtualChild : public VirtualParent {
virtual void foo();
}
VirtualChild vc;
vc.foo(); // calls VirtualChild::foo
VirtualParent &vp = vc;
vp.foo(); // calls VirtualChild::foo
Yes, this is valid C++ syntax and will define a Child::func1 which hides Parent::func1 in Child.
However, this does not mean that it fully replaces Child::Parent::func1. This function can still be called explicitly on an element of child.
Child c;
c.Parent::func1();
Also, this function will not be virtual. Thus, the following..
Child c;
Parent& p = c;
p.func1();
will call Parent::func1 and not Child::func1.
Most has been said.
Your expectations would be right if you talk about java. In java any non-private, non-final method could be overridden. Maybe you are more familiar with an other programming language than C++
By the way, two things are wrong in your code
"class" must be written lower case
the default access of members in class is "private". It is NOT allowed nor useful to override private members which are non-pure

Is calling pure virtual functions indirectly from a constructor always undefined behaviour?

I'm working on building Cppcheck on AIX with the xlC compiler (see previous question). Checker classes all derive from a Check class, whose constructor registers each object in a global list:
check.h
class Check {
public:
Check() {
instances().push_back(this);
instances().sort();
}
static std::list<Check *> &instances();
virtual std::string name() const = 0;
private:
bool operator<(const Check *other) const {
return (name() < other->name());
}
};
checkbufferoverrun.h
class CheckBufferOverrun: public Check {
public:
// ...
std::string name() const {
return "Bounds checking";
}
};
The problem I appear to be having is with the instances().sort() call. sort() will call Check::operator<() which calls Check::name() on each pointer in the static instances() list, but the Check instance that was just added to the list has not yet had its constructor fully run (because it's still inside Check::Check()). Therefore, it should be undefined behaviour to call ->name() on such a pointer before the CheckBufferOverrun constructor has completed.
Is this really undefined behaviour, or am I missing a subtlety here?
Note that I don't think the call to sort() is strictly required, but the effect is that Cppcheck runs all its checkers in a deterministic order. This only affects the output in the order in which errors are detected, which causes causes some test cases to fail because they're expecting the output in a particular order.
Update: The question as above still (mostly) stands. However, I think the real reason why the call to sort() in the constructor wasn't causing problems (ie. crashing by calling a pure virtual function) is that the Check::operator<(const Check *) is never actually called by sort()! Rather, sort() appears to compare the pointers instead. This happens in both g++ and xlC, indicating a problem with the Cppcheck code itself.
Yes, it's undefined. The standard specifically says so in 10.4/6
Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.
It is true that calling a pure virtual function from a constructor is always an undefined behaviour.
The virtual pointer can not be assumed to be set until the constructor has run completely (closing "}"), and hence any call to a virtual function (or pure virtual function) has to be setup at the time of compilation itself (statically bound call).
Now, if the virtual function is pure virtual function, the compiler will generally insert its own implementation for such pure virtual function, the default behavior of which is to generate a segmentation fault. The Standard does not dictate what should be the implementation of a pure virtual function, but most of C++ compilers adopt aforesaid style.
If your code is not causing any runtime mischief demeanour, then it is not getting called in the said call sequence. If you could post the implementation code for below 2 functions
instances().push_back(this);
instances().sort();
then maybe it will help to see what's going on.
As long as object construction isn't finished, a pure virtual function may not be called. However, if it's declared pure virtual in a base class A, then defined in B (derived from A), the constructor of C (derived from B) may call it, since B's construction is complete.
In your case, use a static constructor instead:
class check {
private Check () { ... }
public:
static Check* createInstance() {
Check* check = new Check();
instances().push_back(check);
instances().sort();
}
...
}
I think your real problem is that you've conflated two things: the Checker base class, and some mechanism for registering (derived) instances of Check.
Among other things, this isn't particularly robust: I may want to use your Checker classes, but I may want to register them differently.
Maybe you could do something like this: Checker get a protected ctor (it's abstract anyway, and so only derived classes ought to be calling the Checker ctor).
Derived classes also have protected ctors, and a public static method (the "named constructor pattern") to create instances. That creating method news up a Checker subclass, and them passes it (fully created at this point) to a CheckerRegister class (which is also abstract, so users can implemented their own if need be).
You use whatever singleton pattern, or dependency injection mechanism, that you prefer, to instantiate a Checkerregister and make it available to Checker subclasses.
One simple way to do this would be to have a getCheckerRegister static method on Checker.
So a Checker subclass might look like this:
class CheckBufferOverrun: public Check {
protected:
CheckBufferOverrun : Check("Bounds checking") {
// since every derived has a name, why not just pass it as an arg?
}
public:
CheckBufferOverrun makeCheckBufferOverrun() {
CheckBufferOverrun that = new CheckBufferOverrun();
// get the singleton, pass it something fully constructed
Checker.getCheckerRegister.register(that) ;
return that;
}
If it looks like this will end up being a lot of boilerplate code, write a template. If you worry that because each template instance in C++ is a real and unique class, write a non-templated base class that will register any Checker-derived.