Calling the overriding function through a reference of base class [duplicate] - c++

This question already has answers here:
Difference between calling of virtual function and non virtual function?
(5 answers)
Virtual dispatch implementation details
(3 answers)
Closed 8 months ago.
I googled and learnt the differences between function hiding and function overriding.
I mean I understand the output of testStuff(), which is seen in the below code snippet.
But what confuses me is that a instance of derived class could be assigned to a reference of the base class. And calling the overriding function through the said reference finally invoking the function of the derived class other than the base class.
Could somebody shed some light on this matter?
Here is the code snippet:
#include <iostream>
using namespace std;
class Parent {
public:
void doA() { cout << "doA in Parent" << endl; }
virtual void doB() { cout << "doB in Parent" << endl; }
};
class Child : public Parent {
public:
void doA() { cout << "doA in Child" << endl; }
void doB() { cout << "doB in Child" << endl; }
};
void testStuff() { //I can understand this function well.
Parent* p1 = new Parent();
Parent* p2 = new Child();
Child* cp = new Child();
p1->doA();
p2->doA();
cp->doA();
p1->doB();
p2->doB();
cp->doB();
}
int main()
{
Child cld;
Parent prt = cld;
Parent &ref_prt = cld;
prt.doA();
ref_prt.doA();
prt.doB();
ref_prt.doB(); //The one which most surprised me! I know `Child::doB()` overrides `Parent::doB()`. And I understand the output for `testStuff()`.
//But I still do not understand this line and `Parent &ref_prt=cld`.
return 0;
}
Here is the output:
doA in Parent
doA in Parent
doB in Parent
doB in Child

But what confuses me is that a instance of derived class could be assigned to a reference of the base class. And calling the overriding function through the said reference finally invoking the function of the derived class other than the base class.
It is indeed exactly like that.
If a member function is virtual in a class, then calling it through a pointer-or-reference to that class will result in a dynamic dispatch, so if the actual object is of a derived class which overrides that function (btw, it neededn't declare it virtual because it's already virtual; and it'd better delcare it override, so that it errors out if it doesn't really override, e.g. because you mistyped the name), than that override will be called.
Tha page linked above should sufficient to shed light on this as well as other doubts.

Related

How to make sure overridden function is called

Is there some way that I can make sure that the base classes function is called from the overridden function in the child class.
Example:
#include <iostream>
class Base
{
public:
virtual void func()
{
std::cout << "Really important code was ran" << std::endl;
}
};
class ChildExplicit : public Base
{
void func() override
{
Base::func();
std::cout << "child class explicitly calling Base::func" << std::endl;
}
};
class ChildImplicit : public Base
{
void func() override
{
std::cout << "child not explicitly calling Base::func" << std::endl;
}
};
int main()
{
Base* explicitChild = new ChildExplicit();
Base* implicitChild = new ChildImplicit();
explicitChild->func();
std::cout << std::endl;
implicitChild->func();
}
This should either output this:
Really important code was ran
child class explicitly calling Base::func
Really important code was ran
child not explicitly calling Base::func
or yield some kind of error that Base::func was not called in ChildImplicit::func.
One solution that would be possible is to make func non virtual and creating a second protected function that will be called in Base::func, the child classes would then override the protected function. But as you can imagine if apply this to a Base class of the Base class of the Base class scenario and each of there implementations must be called this gets quite messy. Would there be an other way to achieve the same goal?

Calling overridden method of helper class in C++

I come from a Python background, and currently I'm learning OOP in C++.
I'm having problems figuring out how to get the code to call the correct method in a helper class HelperBase that is inherited to HelperChild.
#include <iostream>
class HelperBase {
public:
HelperBase() {}
virtual void something() {
std::cout << "HelperBase" << std::endl;
}
};
class HelperChild : public HelperBase {
public:
HelperChild() {}
void something() {
std::cout << "HelperChild" << std::endl;
}
};
The HelperBase class i used in the class Base, where it is set as a member variable.
class Base {
public:
Base(HelperBase &helperBase) : hb(helperBase) {}
virtual void print() {
std::cout << "-- Base" << std::endl;
hb.something();
}
HelperBase hb;
};
Then this class is used as the base class of the class Child:
class Child : public Base {
public:
Child(HelperChild &helperChild) : Base(helperChild) {
helperChild.something();
}
};
The main method is
int main() {
HelperChild helperChild;
Child child(helperChild);
child.print();
return 0;
}
This outputs the following:
HelperChild
-- Base
HelperBase
Why isn't the 'HelperChild' printed in the last line? What changes do I have to do to achieve this? (I'm not sure if I have used virtual in the correct way).
EDIT: In the actual case im trying to figure out, Base::print is a really large method that I don't want to override in the Child class. I just want to change the behaviour of the helper class.
Copy constructor will NOT copy derived object, it will get sliced and create a base object.
To elaborate, you may consider copy constructor as "copy by value", every value of derived object would be copied to create a base object. Since your Helper classes have no class members, it copied nothing.
Also function is not copyable, C++ handles virtual functions by vtable. A base class would have a vtable of base class, that's why hb.something() called the base version.
Last line is printing Helper base because your Base has a HelperBase but not a derived HelperChild.
class Base {
public:
Base(HelperBase &helperBase) : hb(helperBase) {} // hp(helperBase) means you still have a helper base.
virtual void print() {
std::cout << "-- Base" << std::endl;
hb.something();
}
HelperBase hb;
};
Then in main, child.print() will call the hb.something() which belongs to HelperBase.
To achieve polymorphism, you need a pointer to take the instance of HelperChild. It's called Dependency Injection and I assumed you were trying to achieve it.
class Base {
public:
Base(HelperBase &helperBase) {
hb = &helperBase;
}
virtual void print() {
std::cout << "-- Base" << std::endl;
hb->something();
}
HelperBase* hb;
};
The HelperBase hb in class Base is always of type HelperBase - even if you call print from an instance of type Child.
There are various ways to achieve what you want. One option is to use PIMPL to store a pointer to a Helper class. A different option is to use CRTP.

Difference between virtual and non virtual function for child class [duplicate]

This question already has answers here:
Virtual function keyword
(2 answers)
Closed 8 years ago.
Let my parent class be;
class parent {
virtual void printx () { cout<< "parent" ; }
}
Case 1:
class child : public parent {
virtual void printx() { cout<< " child" ; }
}
Case 2:
class child : public parent {
void printx() { cout<< " child" ; }
}
Is there any difference if I omit virtual in the child class for the function printx in case 2?
Provided the function signatures are the same, the child class is not required to add the virtual to the method, the compiler will take care of this for you. If a function is declared virtual in a parent class, the child's overridden methods are also virtual.
If C++11 is available, consider adding the override specifier to the overridden method in the child class;
class child : public parent {
void printx() override { cout<< " child" ; }
}
With the override, the compiler will check to make sure that this method does indeed override a virtual method in the base class. If it does not, the compiler will generate an error for you. For example; as in the original posting, it will pick up the spelling difference between printx and pritnx.
Both are same. If a function is declared as virtual in base class then it would be virtual in all derived classes whether you explicitly mention it or not.

C++ Class and virtual method

I am having two problem about virtual methods.
First:
class Parent
{
public:
virtual void SHOW(int x = 5) { cout << "PARENT " << x << endl; }
};
class Child : public Parent
{
public:
virtual void SHOW(int y = 10) { cout << "CHILD " << y << endl; }
};
int main()
{
Child Y;
Parent* P = &Y;
P->SHOW();
getch();
return 0;
}
I think tt should be CHILD 10 but the result is CHILD 5
And another:
class Parent
{
public:
virtual void SHOW() { cout << "PARENT" << endl; }
};
class Child : public Parent
{
private:
virtual void SHOW() { cout << "CHILD" << endl; }
};
int main()
{
Child Y;
Parent* P = &Y;
P->SHOW();
getch();
return 0;
}
It'll show CHILD on the screen. I don't know how a private method which was called from outside?
Thank you. I'm learning English so.. :)
1)
C++ Standard says
A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides.
§8.3.6/10
2)
Overriding public virtual functions with private functions in C++
A virtual function call uses the default arguments in the declaration of the virtual function determined by the static type of the pointer you use to call the function. In your case the static type of P is Parent although the dynamic type resolves to Child. This is according to C++ standard.
This is a good example of why it is typically best to make virtual functions private and public functions non-virtual. Herb Sutter once called this the Non-Virtual Interface Idiom (NVI).
Let's apply it to your code. I'll also change the function name "SHOW" to "show", because all-uppercase in C++ usually denotes a macro. Furthermore, I'll add a virtual destructor, because newbies are reading these questions and they shouldn't see a polymorphic class without one. Note that destructors are an exception to NVI.
Here we go:
class Parent
{
public:
void show(int x = 5) { doShow(x); }
virtual ~Parent() {}
private:
virtual void doShow(int x) { cout << "PARENT " << x << endl; }
};
class Child : public Parent
{
private:
virtual void doShow(int x) { cout << "CHILD " << x << endl; }
};
Default arguments are usually useful for code which uses the objects of a class. That code then uses the public functions.
Parent *p = new Child;
p->show(); // here's where a default argument is a useful feature
delete p;
Inheriting classes, however, are interested in something completely different, namely in the virtual functions of the base class. It turns out that you rarely feel the need for default arguments when you write the code for a subclass.
Bottom line:
Default arguments and virtual functions shouldn't be mixed. There is an item for this in the famous Effective C++ book by Scott Meyers: "Never redefine an inherited default parameter value". You should read that book.
Using NVI, you will typically not have this problem anyway, because it turns out default arguments are more of a thing for public functions, and with NVI, public functions aren't virtual.

base class pointer pointing to normal and virtual function [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
why does base class pointer pointing to derived class object still points to base class function, if the functions are not declared as virtual
class Base
{
public:
void draw() { cout << "base" << endl; }
virtual void fun() { cout << "base class function" << endl; }
};
class Derived : public Base
{
public:
void draw() { cout << "derived" << endl; }
void fun() { cout << "derived function" << endl; }
};
int main()
{
Derived d;
d.draw(); //derived
Base *b = &d;
b->draw(); //base
b->fun(); //derived function
return 0;
}
b is a pointer pointing to derived object even then why does b->draw() gives output as "base" but not "derived" ?
The function will have to be virtual to be overridden. That's what virtual means: that it can be overloaded.
In C++, non-virtual class functions and class variables (i.e. instance variables or fields) are called by class of pointer, not class of object. Java methods are virtual by default
The whole point of the virtual keyword is to decide whether re-definition of a function in a derived class means:
virtual: actual redefinition of the existing function interface
non-virtual: just another unrelated member function with the same signature
In the second case, the actual function you call with:
d.draw();
b->draw();
are defined by the compile-time type of the object you call it on, i.e. a Base instance will call Base::draw, whereas a Derived instance will call Derived::draw. Note that you can also statically call the base-defined method with the same name using:
d.Base::draw();