I want to edit an inherited function name(), and ensure that the inherited function info() will call child::name() rather than parent::name() when called by an instance of child.
class parent {
public:
string name() { return "parent"; }
void info() {
cout << "This class is " << name() << endl;
}
};
class child : public parent {
public:
string name() { return "child"; }
};
int main() {
parent p;
child c;
p.info(); // outputs "parent"
c.info(); // outputs "parent" - I want "child"
}
How can I get c.info() to use child::name()? I will never need name() outside of info(), and I don't really want to duplicate info() in the child class, as I am trying to avoid repeating a rather long block of code in my real problem.
You have declared a non polymorphic function
If a member function f() of your parent is not virtual, it is not polymorphic. So if this function is called by another function of the parent, it is parent::f() that will be called.
If this function is hidden by another function f() in the child, with exactly the same signature, and if this function is called by another function of the child, it is child::f() that will be called.
Interestingly, if you invoke the function directly for an object, the function of the declared type of the object will be invoked.
Polymorphic functions
If you want to make your function polymorphic, you have to define it as virtual in the parent. Suppose it is overriden in the child. In this case, when you call f(), it will always be the f() defined for the real type of the object.
class parent {
public:
virtual string name() { return "parent"; }
...
}
};
class child : public parent {
public:
string name() override { return "child"; }
};
With this programm, you'll get this result:
This class is parent
This class is child
Related
So, I know something like this is asked a lot, but the other answers seem to indicate that this should work, so I thought I'd ask about my code specifically. I spend more time in .NET and Java, so maybe I'm forgetting something.
I'm creating a base widget and a set of specific widgets (buttons, other graphical items). I'm trying to loop through a linked list of widgets and what I would like is for the specific rendering method for that specific widget to be called. Below is simplified code that demonstrates my problem, on my first call to Render, the specific render function is called. If I pass a cGeneralWidget pointer to a function which calls the Render object, the base method was called. I thought, as long as I send a pointer, C++ is smart enough to know what the object really is and call the overridden method.
Otherwise, whats the correct way to deal with a collection of base objects and call the derived methods as appropriate?
Thank you.
class cGeneralWidget
{
public:
void Render()
{
int a = 99;
}
};
class cSpecificWidget : public cGeneralWidget
{
public:
void Render()
{
int a = 99;
}
};
void GeneralRenderingFunction(cGeneralWidget * b)
{
b->Render(); // <-- calls the base function
}
int main(int argc, char* argv[])
{
cSpecificWidget wd;
wd.Render(); // <-- calls the derived function
GeneralRenderingFunction(&wd);
return 0;
}
You should define Render() method in your base class with virtual keyword and in your derived class with override keyword. If you don't put virtual keyword in your base class implementation then C++ wouldn't mark it as virtual.
class cGeneralWidget
{
public:
virtual void Render()
{
int a = 99;
}
};
class cSpecificWidget : public cGeneralWidget
{
public:
void Render() override
{
int a = 99;
}
};
in your base class
class cGeneralWidget
{
public:
virtual void Render()
{
int a = 99;
}
};
Render has to be virtual so it overrides it
Note : A virtual function a member function which is declared within base class and is re-defined (Overriden) by derived class. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class’s version of the function.
Given the following code fragment, what are the differences in the function calls? What is function hiding? What is function overriding? How do they relate to function overloads? What is the difference between the two? I couldn't find a good description of these in one place, so I'm asking here so I can consolidate the information.
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; }
};
Parent* p1 = new Parent();
Parent* p2 = new Child();
Child* cp = new Child();
void testStuff() {
p1->doA();
p2->doA();
cp->doA();
p1->doB();
p2->doB();
cp->doB();
}
What is function hiding?
... is a form of name hiding. A simple example:
void foo(int);
namespace X
{
void foo();
void bar()
{
foo(42); // will not find `::foo`
// because `X::foo` hides it
}
}
This also applies to the name lookup in a base class:
class Base
{
public:
void foo(int);
};
class Derived : public Base
{
public:
void foo();
void bar()
{
foo(42); // will not find `Base::foo`
// because `Derived::foo` hides it
}
};
What is function overriding?
This is linked to the concept of virtual functions. [class.virtual]/2
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.
class Base
{
private:
virtual void vf(int) const &&;
virtual void vf2(int);
virtual Base* vf3(int);
};
class Derived : public Base
{
public: // accessibility doesn't matter!
void vf(int) const &&; // overrides `Base::vf(int) const &&`
void vf2(/*int*/); // does NOT override `Base::vf2`
Derived* vf3(int); // DOES override `Base::vf3` (covariant return type)
};
The final overrider becomes relevant when calling a virtual function: [class.virtual]/2
A virtual member function C::vf of a class object S is a final overrider unless the most derived class of which S is a base class subobject (if any) declares or inherits another member function that overrides vf.
I.e. if you have an object of type S, the final overrider is the first overrider you see when traversing the class hierarchy of S back to its base classes. The important point is that the dynamic type of the function-call expression is used in order to determine the final overrider:
Base* p = new Derived;
p -> vf(42); // dynamic type of `*p` is `Derived`
Base& b = *p;
b . vf(42); // dynamic type of `b` is `Derived`
What is the difference between overriding and hiding?
Essentially, the functions in the base class are always hidden by functions of the same name in a derived class; no matter if the function in the derived class overrides a base class' virtual function or not:
class Base
{
private:
virtual void vf(int);
virtual void vf2(int);
};
class Derived : public Base
{
public:
void vf(); // doesn't override, but hides `Base::vf(int)`
void vf2(int); // overrides and hides `Base::vf2(int)`
};
To find a function name, the static type of an expression is used:
Derived d;
d.vf(42); // `vf` is found as `Derived::vf()`, this call is ill-formed
// (too many arguments)
How do they relate to function overloads?
As "function hiding" is a form of name hiding, all overloads are affected if the name of a function is hidden:
class Base
{
private:
virtual void vf(int);
virtual void vf(double);
};
class Derived : public Base
{
public:
void vf(); // hides `Base::vf(int)` and `Base::vf(double)`
};
For function overriding, only the function in the base class with the same arguments will be overriden; you can of course overload a virtual function:
class Base
{
private:
virtual void vf(int);
virtual void vf(double);
void vf(char); // will be hidden by overrides in a derived class
};
class Derived : public Base
{
public:
void vf(int); // overrides `Base::vf(int)`
void vf(double); // overrides `Base::vf(double)`
};
The difference between calling a virtual member function and calling a non-virtual member function is that, by definition, in the former case the target function is chosen in accordance with the dynamic type of the object expression used in the call, while in the latter case the static type is used.
That's all there is to it. Your example clearly illustrates this difference by p2->doA() and p2->doB() calls. Static type of *p2 expression is Parent, while dynamic type of the same expression is Child. This is why p2->doA() calls Parent::doA and p2->doB() calls Child::doB.
In contexts in which that difference matters, name hiding does not come into the picture at all.
We'll start with the easy ones.
p1 is a Parent pointer, so it will always call Parent's member functions.
cp is a pointer to Child, so it will always call Child's member functions.
Now the more difficult one. p2 is a Parent pointer, but it is pointing to an object of type Child, so it will call Child's functions whenever the matching Parent function is virtual or the function only exists within Child and not in Parent. In other words, Child hides Parent::doA() with its own doA(), but it overrides Parent::doB(). Function hiding is sometimes considered a form of function overloading, because a function with the same name is given a different implementation. Because the hiding function is in a different class than the hidden function, it does have a different signature, which makes it clear which to use.
The output for testStuff() will be
doA in Parent
doA in Parent
doA in Child
doB in Parent
doB in Child
doB in Child
In any case, Parent::doA() and Parent::doB() can be called within Child using name resolution, regardless of the function's "virtual-ness". The function
void Child::doX() {
doA();
doB();
Parent::doA();
Parent::doB();
cout << "doX in Child" << endl;
}
demonstrates this when called by cp->doX() by outputting
doA in Child
doB in Child
doA in Parent
doB in Parent
doX in Child
Additionally, cp->Parent::doA() will call Parent's version of doA().
p2 cannot refer to doX() because it is a Parent*, and Parent doesn't know about anything in Child. However, p2 can be casted to a Child*, since it was initialized as one, and then it can be used to call doX().
A much easier example that differs b/w all of them.
class Base {
public:
virtual int fcn();
};
class D1 : public Base {
public:
// D1 inherits the definition of Base::fcn()
int fcn(int); // parameter list differs from fcn in Base
virtual void f2(); // new virtual function that does not exist in Base
};
class D2 : public D1 {
public:
int fcn(int); // nonvirtual function hides D1::fcn(int)
int fcn(); // overrides virtual fcn from Base
void f2(); // overrides virtual f2 from D1
}
The example code you're writen in the question essentially gives the answer when you run it.
Calling a non-virtual function will use the function from the same class as the pointer type, regardless of whether the object was actually created as some other derived type. Whereas calling a virtual function will use the function from the original allocated object type, regardless of what kind of pointer you're using.
So your program's output in this case will be:
doA in Parent
doA in Parent
doA in Child
doB in Parent
doB in Child
doB in Child
#include<stdio.h>
class parent
{
public:
parent()
{
}
};
class child : public parent
{
public:
child()
{
}
};
class master
{
public:
void view(parent a)
{
printf("view parent instances");
}
void view(child b)
{
printf("view child instances");
}
};
int main()
{
parent *ptr;
master mymaster;
ptr = new child;
mymaster.view(*ptr);
return 0;
}
output : "view parent instances"
I create a pointer from parent class. then I declared that pointer as child type. when i run mymaster.view(*ptr); , this always go to first view function (void view(parent a)), how to make it go to (void view(child b)). thankyou
With a little refactoring and a slightly different approach, you could use virtual functions. This enables the function from derived classes to be used when called using a pointer like below.
#include<stdio.h>
class parent
{
public:
parent()
{
}
virtual void view()
{
printf("View parent");
}
};
class child : public parent
{
public:
child()
{
}
virtual void view()
{
printf("View child");
}
};
class master
{
public:
void view(parent *a)
{
a->view();
}
};
int main()
{
parent *ptr;
master mymaster;
ptr = new child;
mymaster.view(ptr);
return 0;
}
This will output "View child". The same code without the virtual keywords will output "View parent". Note that the keyword only needs to be in the parent class, but is often used in the derived classes too for clarity.
The Wikipedia article on virtual functions explains the situation pretty well:
Virtual functions are resolved 'late'. If the function in question is
'virtual' in the base class, the most-derived class's implementation
of the function is called according to the actual type of the object
referred to, regardless of the declared type of the pointer or
reference. If it is not 'virtual', the method is resolved 'early' and
the function called is selected according to the declared type of the
pointer or reference.
Since the actual type of the object here is a child, the virtual function makes sure that the child's functionality is called even though the pointer is of parent type.
The type of *(parent*) is parent, so the method that gets called is view(parent). If you want to invoke view(child), you need to cast the pointer to a child* before passing it in, however...
You're using OOP backwards. You don't define multiple methods that know how to consume each specific type of sub-class, you define one method that can respect the contract provided by the parent class, and the sub-classes do their own thing internally.
ptr is a pointer to a parent object.
If you want to have the view(child) function called, you need to pass a child object to the function call.
Alternatively, you can cast it to a child pointer
mymaster.view(*(child*)ptr);
but you're likely to end up with all kinds of other problems.
The compiler decides the matching method according to the best choice.
The compiler sees that the variable is of type parent, so it calls the matching method.
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";
}
};
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.