I have, for example, such class:
class Base
{
public: void SomeFunc() { std::cout << "la-la-la\n"; }
};
I derive new one from it:
class Child : public Base
{
void SomeFunc()
{
// Call somehow code from base class
std::cout << "Hello from child\n";
}
};
And I want to see:
la-la-la
Hello from child
Can I call method from derived class?
Sure:
void SomeFunc()
{
Base::SomeFunc();
std::cout << "Hello from child\n";
}
Btw since Base::SomeFunc() is not declared virtual, Derived::SomeFunc() hides it in the base class instead of overriding it, which is surely going to cause some nasty surprises in the long run. So you may want to change your declaration to
public: virtual void SomeFunc() { ... }
This automatically makes Derived::SomeFunc() virtual as well, although you may prefer explicitly declaring it so, for the purpose of clarity.
class Child : public Base
{
void SomeFunc()
{
// Call somehow code from base class
Base::SomeFunc();
std::cout << "Hello from child\n";
}
};
btw you might want to make Derived::SomeFunc public too.
You do this by calling the function again prefixed with the parents class name. You have to prefix the class name because there maybe multiple parents that provide a function named SomeFunc. If there were a free function named SomeFunc and you wished to call that instead ::SomeFunc would get the job done.
class Child : public Base
{
void SomeFunc()
{
Base::SomeFunc();
std::cout << "Hello from child\n";
}
};
Yes, you can. Notice that you given methods the same name without qualifying them as virtual and compiler should notice it too.
class Child : public Base
{
void SomeFunc()
{
Base::SomeFunc();
std::cout << "Hello from child\n";
}
};
Related
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?
How to call the member function of child inside the member function of parent class
This needs to accomplished as a part of gtest and gmock.
Example:
class Base
{
public:
void my_read()
{
cout << "Base read\n";
}
void my_write()
{
cout << "Base write\n";
my_read();
}
};
class Derived: public Base
{
public:
void my_read()
{
cout << "Derived read\n";
}
};
int main()
{
Derived d;
d.my_write();
return 0;
}
The desired output is:
Base write
Derived read
The actual output is:
Base write
Base read
As this is the situation of writing the test case, I cant change the code implementaion.
Considering Derived class as a Mock class from the Base, I have specific implementation for my_read().
How to use this implementation in child without passing any other instances.
Just one solution's seen by me yet, declaring the my_read() with virtual (which modifies the base a bit):
virtual void my_read()
{
std::cout << "Base read\n";
}
Solves your problem. The output was:
Base write
Derived read
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.
I understand the basic concept of virtual function and vtable,
but in the following example, I don't understand why c.A(); prints out
parent A
child
but without the virtual keyword for Parent::func(), it prints out
parent A
parent
Would you let me know the reason in detail? It would be great to explain with v table, memory (heap, stack), etc..
Thanks.
#include <iostream>
template <class TYPE> class Parent
{
public:
Parent() {};
~Parent() {};
virtual void func() { std::cout << "parent" << std::endl; };
void A() {
std::cout << "parent A" << std::endl;
func();
}
};
template <class TYPE> class Child : public Parent <TYPE>
{
public:
Child() {};
~Child() {};
void func() { std::cout << "child" << std::endl; };
};
void main()
{
Child<int> c;
c.A();
}
The virtual key word specifies that the function can be redefined in a derived class, while preserving its calling properties though references. This is basically the trigger for polymorphic behavior. If the function is declared virtual and it is redefined in a derived class then the vtable is utilized to select the appropriate version of the function unless a specific namespace is specified. For example Parent::func(). Despite having the same name, without the key word virtual the two functions you named func() are completely different. There is no reference available to the base class that can access the derived class's version of the function. It uses the only version func() it knows about, which is the one defined in the base class.
#Pemdas gave a nice explanation. Here is my try.
c.A() tells compiler "I am gonna call the non virtual function A defined in my parent class". This translates to Parent::A(&c)
The A method in class Parent translates to "get the vtable of object &c, grab the function pointer in first row, and call it". Since c reimplements the function func, the function pointer would be c's implementation of function func. That would be what you see.
Update: This issue is caused by bad memory usage, see solution at the bottom.
Here's some semi-pseudo code:
class ClassA
{
public:
virtual void VirtualFunction();
void SomeFunction();
}
class ClassB : public ClassA
{
public:
void VirtualFunction();
}
void ClassA::VirtualFunction()
{
// Intentionally empty (code smell?).
}
void ClassA::SomeFunction()
{
VirtualFunction();
}
void ClassB::VirtualFunction()
{
// I'd like this to be called from ClassA::SomeFunction()
std::cout << "Hello world!" << endl;
}
The C# equivalent is as follows: Removed C# example, as it's not relevant to the actual problem.
Why isn't the ClassB::VirtualFunction function being called when called from ClassA::SomeFunction? Instead ClassA::VirtualFunction is being called...
When I force implementation of the virtual function ClassA::VirtualFunction, like so:
class ClassA
{
public:
virtual void VirtualFunction() = 0;
void SomeFunction();
}
class ClassB : public ClassA
{
public:
void VirtualFunction();
}
void ClassA::SomeFunction()
{
VirtualFunction();
}
void ClassB::VirtualFunction()
{
// I'd like this to be called from ClassA::SomeFunction()
std::cout << "Hello world!" << endl;
}
The following error occurs at runtime, despite the derrived function deffinately being declared and defined.
pure virtual method called
terminate called without an active exception
Note: It seems like the error can be caused even by bad memory usage. See self-answer for details.
Update 1 - 4:
Comments removed (not releavnt).
Solution:
Posted as an answer.
class Base {
public:
virtual void f() { std::cout << "Base" << std::endl; }
void call() { f(); }
};
class Derived : public Base {
public:
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main()
{
Derived d;
Base& b = d;
b.call(); // prints Derived
}
If in the Base class you do not want to implement the function you must declare so:
class Base {
public:
virtual void f() = 0; // pure virtual method
void call() { f(); }
};
And the compiler won't allow you to instantiate the class:
int main() {
//Base b; // error b has a pure virtual method
Derived d; // derive provides the implementation: ok
Base & b=d; // ok, the object is Derived, the reference is Base
b.call();
}
As a side note, be careful not to call virtual functions from constructors or destructors as you might get unexpected results.
If you're getting that 'pure virtual method called
terminate called without an active exception' error message, that means you're calling the virtual function from the constructor or destructor of classA (the base class), which you should not do.
on the pure virtual method called error:
You should create a different question as it is in fact different than the other. The answer to this question is on the very last paragraph of my previous answer to your initial question:
Do not call virtual functions from constructors or destructors
class Base
{
public:
Base() { f(); }
virtual void f() = 0;
};
class Derived : public Base
{
public:
virtual void f() {}
};
int main()
{
Derived d; // crashes with pure virtual method called
}
The problem in the code above is that the compiler will allow you to instantiate an object of type Derived (as it is not abstract: all virtual methods are implemented). The construction of a class starts with the construction of all the bases, in this case Base. The compiler will generate the virtual method table for type Base, where the entry for f() is 0 (not implemented in base). The compiler will execute the code in the constructor then. After the Base part has completely been constructed, construction of the Derived element part starts. The compiler will change the virtual table so that the entry for f() points to Derived::f().
If you try calling the method f() while still constructing Base, the entry in the virtual method table is still null and the application crashes.
When A calls VirtualFunction() it will automatically call the version on B. That is the point of virtual functions.
I am not as familiar with the C++ syntax tho. Do you have to declare the function to be virtual at the point of the body as well as in the header?
Alsop, in class B you probably need to mark it as override
in C# its easy. I just don't know the c++ syntax.
public class ClassA
{
public **virtual** void VirtualFunction(){}
public void FooBar()
{
// Will call ClassB.VirtualFunction()
VirtualFunction();
}
}
public class ClassB
{
public **overide** void VirtualFunction()
{
// hello world
}
}
If you want to force the derived classes to implement the VirtualFunction:
class ClassA
{
public:
virtual void VirtualFunction()=0;
void SomeFunction();
}
This is C++. Default the derived function will be called.
If you want to call the base-class function do:
void ClassA::SomeFunction()
{
// ... various lines of code ...
ClassA::VirtualFunction();
}
There's nothing wrong with your code but your sample is incomplete. You do not state where you are calling SomeFunction from.
As has already been pointed out by dribeas you must be careful calling virtual functions from your constructor as the virtual tables are only built up as each class in the hierarchy completes construction.
Edit: The following paragraph of my reply was incorrect. Apologies. It is fine to call SomeFunction from the constructor of ClassB as the vtable is in place (at least) by the end of the initialiser list i.e. once you are in the body of the constructor. It is not fine to call it from ClassA's constructor of course.
Original paragraph:
I suspect you must be calling SomeFunction from the constructor of ClassB at which point only the vtable up to type ClassA will be complete i.e. to the virtual dispatch mechanism your class is still of type ClassA. It only becomes an object of type ClassB when the constructor completes.
To call a virutal function function you need to call via a pointer or a reference.
void ClassA::SomeFunction()
{
VirtualFunction(); // Call ClassA::VirtualFunction
this->VirtualFunction(); // Call Via the virtual dispatch mechanism
// So in this case call ClassB::VirtualFunction
}
You need to be able to distinguish the two different types of call otherwise the classA::VirtualFunction() becomes inaccessible when it is overridden.
As pointed out by others if you want to make the base class version abstract then use the = 0 rather than {}
class A
{
virtual void VirtualFunction() =0;
....
But sometimes it is legitimate to have an empty definition. This will depend on your exact usage.
You aren't defining the function in ClassB correctly, it should be:
public class ClassB
{
public void override AbstractFunction()
{
// hello world
}
}
Then, any call from the base class to virtual/abstract methods will call the implementation on the derived instance.