C++ Virtual Void vs no virtual [duplicate] - c++

This question already has answers here:
Why do we need virtual functions in C++?
(27 answers)
Overriding non-virtual methods
(3 answers)
Closed 4 years ago.
I'm confused about virtual functions. I was told that virtual in parent class means I can override it in child class. However if I omit the virtual in parent class, I'm still able to override it.
#include <iostream>
using namespace std;
class Enemy{
public:
//if I remove virtual, it still gets overriden in child class
virtual void attack(){
cout << "Attack Enemy!" << endl;
}
};
class Minion : public Enemy {
public:
void attack(){
cout << "Attack Minon!" << endl;
}
};
int main() {
Minion m;
m.attack();
}

If a function is virtual, the call is dynamically dispatched to the implementation provided by the derived type through the vtable at runtime, whereas without, the compiler looks at the object at compile time and selects the class-method of the static type. If you have a pointer to the base-class this means that the base-implementation is used, if the function is not virtual:
Enemy *e = new Minion(); e->attack();
will print "Attack Enemy!" if attack is not virtual. When using a virtual function, the compiler will insert some logic to lookup the right implementation at run-time, and, when e->attack() gets executed, look up the implementation in the vtable of the object pointer to by e, finding that Minion overrides attack, and thus printing "Attack Minion!".
If you want to force your derived classes to override the base-class method you can also make the function purely virtual by using
virtual void attack() = 0;

You can override the method in question and ideally declare that with the override keyword to allow the compiler to complain when you aren't overriding anything.
class Enemy {
public:
virtual ~Enemy() = default; /* Don't forget... or non-virtual protected. */
virtual void attack() {}
};
class Minion : public Enemy {
public:
void attack() override {}
};
Your confusion probably stems from the fact that you can equally well shadow the base class method.
class Enemy {
public:
virtual ~Enemy() = default;
void attack() {}
};
class Minion : public Enemy {
public:
void attack() {}
};
This does not only do something different, it would in addition be an example for extraordinarily poor naming, as it's confusing to the reader: Equal member function names with identical signatures in the context of a class hierarchy are inevitably associated with overridden methods.

You haven't overriden it, you have simply added another method with the same signature.
Enemy* enemy = new Minion();
enemy->attack();
delete enemy;
If this calls the code from Minion you did it right. If it calls the code from Enemy, you did something wrong. You will need virtual to do it right.

Related

Why would I want to implement virtual functions without implementation in an abstract class?

I am sorry but I have to ask a stupid question.
I understand the benefit of implementing an abstract class as such. If I have virtual function with a basic implementation that is always called in cases when the derived classes don't have a specific implementation there is definitely a benefit, e.g.
virtual void ImplementedVirtFunc() {//do something basic}
What I don't quite get is what is the benefit of implementing a purely virtual function such as
virtual void VirtFunc() = 0;
In this case my derived classes need to implement the specialisized function anyhow if they need it. But I could straight forwardly just implement it there and omit the virtual void VirtFunc() = 0 line in my abstract class.
So is there a specific benefit for implementing virtual void VirtFunc() = 0 that I don't see?
Please forgive me this stupid question. I started to learn C++ this January and I am still have a long way to go to understand all the subtleties...
But I could straight forwardly just implement it there and omit the virtual void VirtFunc() = 0 line in my abstract class.
Sure, you could. But you wouldn't be able to call that method from your base class, since your base class doesn't know anything about its existence at all.
Consider the following example. Every Shape definitely has an area, even though not known for a general shape. And every subclass of Shape inherits the Print() method.
class Shape {
// ...
public:
virtual int Area() = 0; // there is no formula for the area of a "general" shape, but it definitely has one ...
virtual void Print() {
std::cout << "Area: " << Area() << std::endl;
}
}
class Circle : public Shape {
// ...
public:
virtual int Area() {
// calculate and return circle area
}
}
class Square : public Shape {
// ...
public:
virtual int Area() {
// calculate and return square area
}
}
virtual void f(); // virtual member function
virtual void g() = 0; // pure abstract member function
A class with at least one pure virtual member function is an abstract class, and cannot be constructed itself, which is often desired (only non-abstract, "concrete" if you will, derive classes should be able to be constructed);
struct Abstract {
virtual void g() = 0;
};
struct NonAbstract {
virtual void f() {}
};
int main() {
NonAbstract na{}; // OK
Abstract a{}; // Error: cannot declare variable 'a'
// to be of abstract type 'Abstract'
}
Abstract classes are typically used polymorphically, to allow dynamic dispatch to derived object methods:
struct Derived : public Abstract {
void g() override {} // #1
}
void h(Abstract const& obj) {
obj.g(); // dynamic dispatch
}
int main() {
Derived d{};
h(d); // Will result in invoke #1
}
There are two reasons.
One is to force the derived concrete class to implement your virtual function.
The second is to make your class an abstract class, which cannot be instantiated by itself.

Method Overriding C++

I got a Question in my Exam which was this:
Function Overriding means the functions have the same prototype but
differ in their body
Justify the Statement with the help of an Example.
Now I quoted this code snippet as Example :
#include<iostream>
using namespace std;
class A {
public: virtual void print() {
cout << "I am Base Class's print Function" << endl;
}
};
class B: public A {
public: void print() {
cout << "I am Derived's Class print function" << endl;
}
};
Here I have made two classes, Class A and Class B and Class B is inheriting Class A. Now, by definition of Method Overriding, we mean that the Function which gets created in the Base Class gets overridden in the Derived Class.
I made the Function in the Base Class as a Virtual Function.
Now, my main() file:
int main() {
A * a1;
B b1;
a1 = & b1;
a1 - > print();
}
Now, I want to ask that is my above code snippet example for above question is right or not. I have performed Function Overriding at run time. In my main file, the Base Class Object is a Pointer that is having the Address of the Derived Class. When I will call print() function using a1, it will execute the print() function of the Derived Class.
So isn't my example justified? Am I right or not?
You could use the classical Cat vs Dog example where both classes inherit from a common base class, i.e. Animal. The common base class can then have a pure virtual function that is then overridden with a differing implementation (method body) in each subclass.
#include <iostream>
class Animal
{
public:
virtual ~Animal() = default;
virtual void MakeSound() const = 0;
};
class Dog : public Animal
{
public:
virtual void MakeSound() const override;
};
class Cat : public Animal
{
public:
virtual void MakeSound() const override;
};
void Dog::MakeSound() const
{
std::cout << "Woof!" << std::endl;
}
void Cat::MakeSound() const
{
std::cout << "Meow!" << std::endl;
}
int main()
{
const Dog dog{};
const Cat cat{};
const Animal& firstAnimal{dog};
const Animal& secondAnimal{cat};
/*
* These functions have the same prototype, void MakeSound(),
* but differ in their implementation.
*/
firstAnimal.MakeSound();
secondAnimal.MakeSound();
return 0;
}
If you teacher expected this as answer and considers your example as wrong then I would argue that they teach you overriding the wrong way.
From cppreference:
Virtual functions are member functions whose behavior can be overridden in derived classes.
Of course this does not strictly imply the reverse statement: "functions that can be overriden are virtual". But if this wasnt true, the quoted sentence would make little sense.
Non-virtual methods are not really meant to be overriden. From the C++ FAQ:
Should a derived class redefine (“override”) a member function that is non-virtual in a base class?
It’s legal, but it ain’t moral. [...]
Note that they put "override" in quotes, because strictly speaking it is not overriding but merely redefining.
Further, you can read on cpprefernce about the override specifier (emphasize mine):
In a member function declaration or definition, override ensures that the function is virtual and is overriding a virtual function from a base class. The program is ill-formed (a compile-time error is generated) if this is not true.
TL;DR If I had to judge I would consider this as a misleading bad example for overriding, while your code seems fine. It could benefit from using override and A should have a virtual destructor, but thats details.

Overloaded function in derived class with Polymorphism (C++)

Considering this code example:
#include <iostream>
using namespace std;
class Base
{
private:
int number;
public:
Base():number(10){}
~Base(){}
virtual void print()
{
cout << "Base class" << endl;
}
};
class Derived : public Base
{
public:
Derived():Base(){}
~Derived(){}
void print(int value)
{
//printing number in Base class and paramter value
cout << "Derived with value " << value << " number is" << number << endl;
}
};
I wanted to use polymorphism and call theoverloaded print() function.
So use these classes as follows:
void somewhere_else()
{
Base* polymorphism = new Derived();
polymorphism->print(5); //Error indicating there are too many parameter
//thinking that I am trying to use print in Base class
((Derived*)polymorphism)->print(5)
//This works as I am casting the variable as Derived variable
}
Unfortunately, I can't call print() from the base class pointer (compilation error, see comment above). I can only call it with a cast.
Is there a better way to keep the polymorphism and still calls overloaded function based on derived class?
In your code you have two different member functions, that have different signatures:
a virtual print() that takes no argument. It is declared and defined in Base, and inherited in Derived
a non-virtual print() that takes one int argument. It is declared and defined ONLY for Derived
So the base object doesn't know a print function with an int parameter. This is why you need to cast (which is by the way a symptom that should ring alarm bells if you need it).
How to improve ?
First, if you want to override a virtual function in a derived class, use the keyword override:
class Derived : public Base
{
public:
Derived():Base(){}
~Derived(){}
void print(int value) override
{
...
}
};
This will ensure an error message in case of subtle mismatch in the function signature:
prog.cpp:23:10: error: ‘void Derived::print(int)’ marked ‘override’, but does not override
void print(int value) override
^~~~~
Then make sure that the signatures are aligned in the base class and derived class (i.e. either both take an int argument or non of them.
Note that you can't access a private member of the base class in a derived class. You have to define number as protected to print it in Derived.
Finally, if you have a base class having a virtual member, it is a sound practice to systematically make the destructor virtual. This will avoid subtle bugs for more complex classes:
class Base
{
protected:
int number;
public:
Base():number(10){}
virtual ~Base(){}
virtual void print(int value)
{
...
}
};
Here the online demo
Now that the things are working, here a short article making the difference between overload and override.

override c++ virtual method

I have a class template where some methods are defined as virtual to give the ability for the user of my class to give an implementation for them in his derived class. Note that in my template class there is some non-virtual methods that makes use of the virtual one (a virtual class that should return a value is called in a non-virtual class).
Can you give me a simple example of a correct code where the virtual method of the parent class should return a value (but it's implementation is provided in a child class) and the value returned by the virtual method in the parent class is used in other methods of that class. Because I saw somewhere (for example here: Safely override C++ virtual functions) that this can cause some problems and the user defined method will note override the virtual method of the parent class.
Note: I program with Code::Blocks using g++ compiler.
EDIT: as requested here a simple example of what I want:
template<typename T>
class parent {
public:
// Public methods that user can call
int getSomething(T t);
void putSomething(T t, int x);
// public method that user should implement in his code
virtual float compute(T t) { }
// protected or private methods and attributes used internally by putSomething ...
float doComplexeThings(...); // this can call
};
The method compute() should be implemented by the user (the child class). However, this method compute() is called by putSomething() and doComplexeThings() for example.
If you can use C++11 features in your compiler then overrides can be tagged as so with the override special identifier:
float compute() override;
The above line in a derived class will cause a compiler error as the function does not override a member function in the base (incorrect signature, missing argument). But note that this must be done in each derived class, it is not a solution that you can impose from the base class.
From the base class you can only force the override by making the function pure virtual, but that changes the semantics. It does not avoid problems while overriding, but rather forces overriding in all cases. I would avoid this approach, and if you are to follow it and there is a sensible implementation for the base type, make the function virtual and provide a definition so that your derived classes's implementation can just call the functions the base type (i.e. you force the implementation, but in the simplest cases it will just forward the call to the parent)
You just have to make sure that the methods have the same signature (including const/mutable modifiers and argument types). You can use a pure virtual definition to provoke compiler errors if you fail to override the function in a subclass.
class parent {
public:
// pure virtual method must be provided in subclass
virtual void handle_event(int something) = 0;
};
class child : public parent {
public:
virtual void handle_event(int something) {
// new exciting code
}
};
class incomplete_child : public parent {
public:
virtual void handle_event(int something) const {
// does not override the pure virtual method
}
};
int main() {
parent *p = new child();
p->handle_event(1); // will call child::handle_event
parent *p = new incomplete_child(); // will not compile because handle_event
// was not correctly overridden
}
This question is asked in 2013. It's pretty old but I found something new which doesn't exist in the answers.
We need to understanding three concept is overload, overwrite, and hide.
Short answer, you want to overload the inheritance function from base class.
However, overload is the mechanism to add multiple behavior for function which needs all these functions under the same scale. But the virtual function is in the Base class obviously.
class A {
public:
virtual void print() {
cout << id_ << std::endl;
}
private:
string id_ = "A";
};
class B : A {
public:
using A::print;
void print(string id) {
std::cout << id << std::endl;
}
};
int main(int argc, char const *argv[]) {
/* code */
A a;
a.print();
B b;
b.print();
b.print("B");
return 0;
}
Add using A::print; in your derive class will do the work!
Though I don't feel it's a good idea since the philosophy behind the overload and inheritance is different, it may not a good idea to nest them together.

c++: explain this function declaration

class PageNavigator {
public:
// Opens a URL with the given disposition. The transition specifies how this
// navigation should be recorded in the history system (for example, typed).
virtual void OpenURL(const GURL& url, const GURL& referrer,
WindowOpenDisposition disposition,
PageTransition::Type transition) = 0;
};
I don't understand what is that =0; part...what are we trying to communicate?
'= 0' means it's a pure virtual method. It must be overriden in inheriting class.
If a class has a pure virtual method it is considered abstract. Instances (objects) of abstract classes cannot be created. They are intended to be used as base classes only.
Curious detail: '= 0' doesn't mean method has no definition (no body). You can still provide method body, e.g.:
class A
{
public:
virtual void f() = 0;
virtual ~A() {}
};
void A::f()
{
std::cout << "This is A::f.\n";
}
class B : public A
{
public:
void f();
}
void B::f()
{
A::f();
std::cout << "And this is B::f.\n";
}
It's a pure virtual function - there's no definition in the base class, making this an abstract class, and any instantiable class that inherits from PageNavigator must define this function.
The = 0 means the function is a pure virtual or abstract function, which in practice means two things:
a) A class with an abstract function is an abstract class. You cannot instantiate an abstract class.
b) You have to define a subclass which overrides it with an implementation.