Nested polymorphism in C++ using virtual fucntions [duplicate] - c++

This question already has answers here:
C++ "virtual" keyword for functions in derived classes. Is it necessary?
(9 answers)
Closed 2 years ago.
#include <iostream>
class base {
public:
virtual void print(){
std::cout << "base\n";
}
};
class dr : public base {
public:
void print(){
std::cout << "dr\n";
}
};
class last : public dr {
public:
void print(){
std::cout << "last\n";
}
};
int main(){
dr *d = new last();
d->print();
return 0;
}
In the above code, only the base class includes a virtual function.
dr and last do not include a virtual function and yet polymorphism is still working.
The output of this code is last. (It should have been dr without polymorphism kicking in).
Does this mean polymorphism works as long as some base class has a virtual function, even though non of the derived classes have one?

Both dr::print and last::print override base::print, they're virtual functions too; the keyword virtual is optional here.
(emphasis mine)
Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration) and overrides Base::vf (whether or not the word override is used in its declaration).

Related

c++ non virtual function acts like virtual function [duplicate]

This question already has an answer here:
method in the derived class got executed without a *virtual* keyword in the referred class
(1 answer)
Closed 2 years ago.
Probably, i misunderstood c++ polymorphism(virtual function).
Please point me what i miss.
the source code is below
#include <iostream>
using namespace std;
class A {
public:
virtual void print(void) {
cout<<"class A"<<endl;
}
};
class B : public A {
public:
void print(void) {
cout<<"class B"<<endl;
}
};
class C : public B {
public:
void print(void) {
cout<<"class C"<<endl;
}
};
int main() {
A a;
B b;
C c;
A *pAa = &a;
A *pAb = &b;
A *pAc = &c;
B *pBc = &c;
pAa->print();
pAb->print();
pAc->print();
pBc->print(); // shouldn't be "class B"
return 0;
}
result
------------------------------
class A
class B
class C
class C // shouldn't be "class B"
my understanding is that
the last print statement should print "class B"
because pBc is a pointer of class B and the print function in class B is non virtual member function. i could not find the answer about this situation.
please tell me why or point me where i can find the answer and
understand c++ polymorphism in comprehension.
thanks.
If a function with a given signature is declared as virtual in a top-level base class, then the function is virtual in all derived classes no matter if it is marked with the keyword virtual (override, final) or not:
virtual function specifier
Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration)
struct Base {
// Pure virtual function.
virtual void foo() const = 0;
};
struct A : public Base {
// Overriding virtual function, even if it
// is not marked as virtual (override, or final).
void foo() const {}
};
In A, adding the virtual specifier to foo() would only bring semantic value; it will be no functional difference whether virtual is omitted or not (unless someone changes the interface in Base).
Many static analyzers enforce(1) marking derived virtual functions with override or final, for two reasons:
semantics; clearly showing the given function is a virtual function (as per being defined so higher up in the inheritance chain), and
enforcement; if a function is marked as override and final but is not actually an overriding function, you will get a compiler error, which can be particularly useful to protect against mistakes when changing a base class interface (whilst forgetting which classes that actually implements this interface).
E.g.:
struct Base {
// Pure virtual function.
virtual void foo() const = 0;
};
struct A : public Base {
// Overriding virtual function.
void foo() const override {}
};
struct B final : public Base {
// Overriding (final) virtual function.
void foo() const final {}
// Error: Function does not override.
// void bar() const override {}
};
(1) E.g. Rule A10-3-1 in the Autsar C++14 Language Guidelines (safety-critical development in automotive) is categorized as a required rule: Virtual function declaration shall contain exactly one of the three specifiers:(1) virtual, (2) override, (3) final.
the print function in class B is non virtual member function
No. Since A::print is marked as virtual and B inherits from A, then B::print is virtual too; regardless of the keywork virtual is specified on it or not.
(emphasis mine)
If some member function vf is declared as virtual in a class Base, and
some class Derived, which is derived, directly or indirectly, from
Base, has a declaration for member function with the same
name
parameter type list (but not the return type)
cv-qualifiers
ref-qualifiers
Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration) and overrides Base::vf (whether or not the word override is used in its declaration).

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.

C++ Virtual Void vs no virtual [duplicate]

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.

Why virtual functions defy access specifiers ? C++ [duplicate]

This question already has answers here:
Public virtual function derived private in C++
(3 answers)
Closed 6 years ago.
let's assume u have a class base and class A which inherits from base . base have a declaration of a pure virtual functions called getValue() which is public , and A contains the definition(implementation) of the functions which is set as private .
When trying to use the function getValue() from base reference or pointer (base& /base*) to an A object it access it even though it's declared as private
Because in C++, virtuality and access are orthogonal concerns. When the compiler sees a base* or base& and it needs to call getValue on it, then it's sufficient that the function is accessible in base.
The fact that A declares its (overriding) getValue as private is irrelevant. After all, how could it be relevant? When base.getValue() or base->getValue() is called, you don't know that you might be dealing with an A. That's the whole point of object-oriented programming in the first place!
This does not mean that it's good style to vary access specifiers within a class hierarchy, though, because it can be confusing. In fact, you should split your getValue into two different functions, one being virtual and the other one non-virtual.
Long story: C++ behaves very different from other popular programming languages here, because it actually allows and encourages private virtual functions. Virtual member functions should be private by default, and public member functions should be non-virtual by default, and call the private virtual ones if necessary. (The only exception is the destructor, of course.) Herb Sutter once called this the Non-Virtual Interface Idiom.
Example:
#include <iostream>
class Base
{
public:
virtual ~Base() {}
int getValue() const
{
int const value = doGetValue();
if (value < 0)
{
// error
}
return value;
}
private:
virtual int doGetValue() const = 0;
};
class A : public Base
{
private:
int doGetValue() const override
{
return 123;
}
};
int main()
{
Base* ptr = new A; // use std::unique_ptr in real code
std::cout << ptr->getValue() << "\n";
delete ptr;
}

using a method declared pure virtual in derived classes [duplicate]

This question already has answers here:
Pure virtual function with implementation
(10 answers)
Closed 7 years ago.
I am working with a code and I saw something odd, a method of a class "MyClass" let's call it X() :
virtual void X() = 0;
So MyClass is an abstract class and in MyClass.cpp X() has a proper implementation...
In derived classes of MyClass, this method is called via MyClass::X();
I thought that = 0 would invalidate its implementation... but it's not the case and it is, in fact, usable in derived classes.
Can you please tell what the compiler really do when he encounters = 0 ?
From the standard (9.2 Class members [class.mem]):
= 0 is the pure-specifier
It tells that compiler that:
the class is abstract
the method will be defined outside the class definition
(usually in a derived class)
Example 1 (build fails)
If I understand your question correctly, you have something like that:
class MyClass {
public:
virtual void X() = 0;
};
class MyDerivedClass : MyClass {
public:
virtual void X();
};
void MyDerivedClass::X() { MyClass::X(); }
int main()
{
MyDerivedClass mdc;
mdc.X();
return 0;
}
If so, the build should fail with:
Error:
undefined reference to 'MyClass::X()'
Example 2 (build succeeds)
However, even if the method MyClass::X() is declared as pure virtual,
you can provide a definition. The following would work. The class MyClass
is still abstract, but you can call the method MyClass::X().
#include <iostream>
class MyClass {
public:
virtual void X() = 0; // pure virtual method
};
class MyDerivedClass : MyClass {
public:
virtual void X();
};
void MyClass::X() { // pure virtual method definition
std::cout << "MyClass::X()" << std::endl;
}
void MyDerivedClass::X() {
MyClass::X();
std::cout << "MyDerivedClass::X()" << std::endl;
}
int main()
{
MyDerivedClass mdc;
mdc.X();
return 0;
}
Output:
MyClass::X()
MyDerivedClass::X()
The =0 thing tells the compiler two things:
A regular out-of-class function definition is not required (though allowed). If there is no such definition, and the function is actually called, this is a runtine error.
The class is abstract and cannot be instantiated, whether a definition from point 1 is present or not. Attempts to do so should be flagged as compile time errors. Derived classes that don't override the function are abstract too.
You could not create instance of class with pure virtual methods, but in some cases you can call pure virtual methods, and it will be an error
I think the compiler creates a vtable with NULL pointers for pure virtual methods.