Question about Inheritance Hierarchy without any virtual function - c++

Imagine if I have class hierachy like this (Inheritance Hierarchy A):
Vehicle
MotorVehicle
Automobile
Motorcycle
WaterCraft
Sailboat
Canoe
If the Vehicle class contains functions named get_retail_price() and get_description(), and the get_description() function is overridden by every subclass in the hierarchy, without a virtual function in the base class, which get_description() function is executed by the following code?
void display_vehicle(const Vehicle& v)
{
std::cout << "Description: " << v.get_description() << ā€˜\nā€™
<< "Retail price: " << v.get_retail_price() << "\n\n";
}
int main()
{
Motorcycle motorcycle("Harley-Davidson FXDR 114", 21349.0);
display_vehicle(motorcycle);
return 0;
}
I think it is the one in the Vehicle class because every subclass is redefining the get_descritption() function. But it the Vehicle class that calls it. Am I right to assume this?
And last question, what would happen if display_vehicle(const Vechicle& v) had a return type of any class? Something like Automobile display_vehicle(const Vehicle& v). Will it still call get_description() in the Vehicle class?

For member functions that are not virtual, it's the function of the known type that is invoked.
Here, the only known type is Vehicle:
void display_vehicle(const Vehicle& v)
{
std::cout << "Description: " << v.get_description() << ā€˜\nā€™
<< "Retail price: " << v.get_retail_price() << "\n\n";
}
Note by the way that in such a case, you don't override the funcions. But you define a new function which hides the function of the base class.
If the function would be virtual, it would be the function of the object's real type that would be called.
Here a small snippet to show the different cases:
class Vehicle {
public:
virtual void show() { cout<<"I'm a vehicle"<<endl; } // virtual
void print() { cout <<"I'm a vehicle"<<endl; } // not virtual
void invokeshow() { show(); } // not virtual but invoking virtual
void invokespecificshow() { Vehicle::show(); } // not virtual invoking specific
~Vehicle() {} //at least one virtual ? then virtual destructor
};
class Motorcycle: public Vehicle {
public:
void show() override { cout<<"I'm a motorcycle"<<endl; }
void print() { cout <<"I'm a motorcycle"<<endl; }
};
void test(Vehicle &v) {
v.show();
v.print();
v.invokeshow();
v.invokespecificshow();
}
Online demo

Related

c++ how to overwrite method in subclass

I have some code I'm trying to get to work, I'm open to other suggestions on how to do this. Basically, I have some base class that I want a bunch of subclasses to inherit. I then have a function that needs to call the subclass version of this method.
#include <iostream>
using namespace std;
//my base class
class BaseClass {
public:
void myMethod(){
std::cout << "Base class?" << std::endl;
}
};
/my subclass
class SubClass1: public BaseClass{
public:
void myMethod(){
std::cout << "Subclass?" << std::endl;
}
};
//method that I want to call SubClass.myMethod(). I cannot declare this as
//SubClass1 because there will be multiple of these.
void call_method(BaseClass object){
return object.myMethod();
}
int main()
{
BaseClass bc;
SubClass1 sb1;
//works how I expect it to
sb1.myMethod();
//I want this to also print "Subclass?"
//but it prints "Base class?".
call_method(sb1);
return 0;
}
Thanks for your help
You need to declare the member function in the base class as virtual. For example
virtual void myMethod() const {
std::cout << "Base class?" << std::endl;
}
And in the derived class to override it
void myMethod() const override {
std::cout << "Subclass?" << std::endl;
}
And the function call_method must have a parameter that represents a reference to base class object
void call_method( const BaseClass &object){
object.myMethod();
}

C++ diamond problem - How to call base method only once

I'm using multiple inheritance in C++ and extending base methods by calling their base explicitly. Assume the following hierarchy:
Creature
/ \
Swimmer Flier
\ /
Duck
Which corresponds to
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Flier::print();
Swimmer::print();
std::cout << "I'm a duck" << std::endl;
}
};
Now this presents a problem - calling the duck's print method calls its respective base methods, all of which in turn call the Creature::print() method, so it ends up being called twice-
I'm a creature
I can fly
I'm a creature
I can swim
I'm a duck
I would like to find a way to make sure the base method is called only once. Something similar to the way virtual inheritance works (calling the base constructor on the first call, then only assigning a pointer to it on successive calls from other derived classes).
Is there some built-in way to do this or do we need to resort to implementing one ourselves?
If so, how would you approach this?
The question isn't specific to printing. I wondered if there's a mechanism for extending base methods and functionality while keeping the call order and avoiding the diamond problem.
I understand now that the most prominent solution would be to add helper methods, but I just wondered if there's a "cleaner" way.
Most likely this is a XY problem. But ... just don't call it twice.
#include <iostream>
class Creature
{
public:
virtual void identify()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a swimmer\n";
}
virtual void tell_ability()
{
std::cout << "I can swim\n";
}
};
class Flier : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a flier\n";
}
virtual void tell_ability()
{
std::cout << "I can fly\n";
}
};
class Duck : public Flier, public Swimmer
{
public:
virtual void tell_ability() override
{
Flier::tell_ability();
Swimmer::tell_ability();
}
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a duck\n";
}
};
int main()
{
Creature c;
c.identify();
std::cout << "------------------\n";
Swimmer s;
s.identify();
std::cout << "------------------\n";
Flier f;
f.identify();
std::cout << "------------------\n";
Duck d;
d.identify();
std::cout << "------------------\n";
}
Output:
I'm a creature
------------------
I'm a creature
I can swim
I'm a swimmer
------------------
I'm a creature
I can fly
I'm a flier
------------------
I'm a creature
I can fly
I can swim
I'm a duck
------------------
We can let the base class keep track of the attributes:
#include <iostream>
#include <string>
#include <vector>
using namespace std::string_literals;
class Creature
{
public:
std::string const attribute{"I'm a creature"s};
std::vector<std::string> attributes{attribute};
virtual void print()
{
for (auto& i : attributes)
std::cout << i << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { attributes.push_back(attribute); }
std::string const attribute{"I can swim"s};
};
class Flier : public virtual Creature
{
public:
Flier() { attributes.push_back(attribute); }
std::string const attribute{"I can fly"s};
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { attributes.push_back(attribute); }
std::string const attribute{"I'm a duck"s};
};
int main()
{
Duck d;
d.print();
}
Likewise, if it is not just printing we're after, but rather the function calls, then we could let the base class keep track of the functions:
#include <iostream>
#include <functional>
#include <vector>
class Creature
{
public:
std::vector<std::function<void()>> print_functions{[this] {Creature::print_this(); }};
virtual void print_this()
{
std::cout << "I'm a creature" << std::endl;
}
void print()
{
for (auto& f : print_functions)
f();
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { print_functions.push_back([this] {Swimmer::print_this(); }); }
void print_this()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
Flier() { print_functions.push_back([this] {Flier::print_this(); }); }
void print_this()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { print_functions.push_back([this] {Duck::print_this(); }); }
void print_this()
{
std::cout << "I'm a duck" << std::endl;
}
};
int main()
{
Duck d;
d.print();
}
An easy way is to create a bunch of helper classes that mimick the inheritance structure of your main hierarchy and do all the printing in their constructors.
struct CreaturePrinter {
CreaturePrinter() {
std::cout << "I'm a creature\n";
}
};
struct FlierPrinter: virtual CreaturePrinter ...
struct SwimmerPrinter: virtual CreaturePrinter ...
struct DuckPrinter: FlierPrinter, SwimmerPrinter ...
Then each print method in the main hierarchy just creates the corresponding helper class. No manual chaining.
For maintainability you can make each printer class nested in its corresponding main class.
Naturally in most real world cases you want to pass a reference to the main object as an argument to the constructor of its helper.
Your explicit calls to the print methods form the crux of the issue.
One way round this would be to drop the print calls, and replace them with say
void queue(std::set<std::string>& data)
and you accumulate the print messages into the set. Then it doesn't matter those functions in the hierarchy get called more than once.
You then implement the printing of the set in a single method in Creature.
If you want to preserve the order of printing, then you'd need to replace the set with another container that respects the order of insertion and rejects duplicates.
If you want that middle class method, do not call the base class method. The easiest and simplest way is to extract extra methods, and then reimplementing Print is easy.
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Creature::Print();
Flier::detailPrint();
Swimmer::detailPrint();
detailPrint();
}
void detailPrint()
{
std::cout << "I'm a duck" << std::endl;
}
};
Without details what is your actual problem is, it hard to come up with a better solution.
Use:
template<typename Base, typename Derived>
bool is_dominant_descendant(Derived * x) {
return std::abs(
std::distance(
static_cast<char*>(static_cast<void*>(x)),
static_cast<char*>(static_cast<void*>(dynamic_cast<Base*>(x)))
)
) <= sizeof(Derived);
};
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Walker : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can walk" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer, public Walker
{
public:
void print()
{
Walker::print();
Swimmer::print();
Flier::print();
std::cout << "I'm a duck" << std::endl;
}
};
And with Visual Studio 2015 the output is:
I'm a creature
I can walk
I can swim
I can fly
I'm a duck
But is_dominant_descendant does not have a portable definition. I wish it were a standard concept.
You are asking for something like inheritance on a function level that automatically calls the inherited function and just adds more code. Also you want it to be done in a virtual way just like class inheritance. Pseudo syntax:
class Swimmer : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
// Inherit from both prints. As they were created using "virtual function inheritance",
// this will "mix" them just like in virtual class inheritance
void print() : Flier::print(), Swimmer::print()
{
std::cout << "I'm a duck" << std::endl;
}
};
So the answer to your question
Is there some built-in way to do this?
is no. Something like this does not exist in C++. Also, I'm not aware of any other language that has something like this. But it is an interesting idea...

C++ virtual inheritance no member named in base class

I'm trying to solve an inheritance problem, where a derived class Snake inherits from LivingThing -> Animal -> Reptile, however, when I don't add virtual void crawl() to class LivingThing, the compiler says error: no member named 'crawl' in 'LivingThing'. Now I don't want to have to implement a virtual void in LivingThing which is specific for Snakes.
#include <iostream>
class LivingThing
{
public:
void breathe()
{
std::cout << "I'm breathing as a living thing." << std::endl;
}
virtual void crawl() {} //dont' want this
};
class Animal : virtual public LivingThing
{
public:
void breathe()
{
std::cout << "I'm breathing as an animal." << std::endl;
}
};
class Reptile : virtual public LivingThing
{
public:
void crawl()
{
std::cout << "I'm crawling as a reptile." << std::endl;
}
void breathe()
{
std::cout << "I'm breathing as a reptile." << std::endl;
}
};
class Snake : public Animal, public Reptile
{
public:
void breathe()
{
std::cout << "I'm breathing as a snake." << std::endl;
}
void crawl()
{
std::cout << "I'm crawling as a snake." << std::endl;
}
};
int main()
{
LivingThing *snake = new Snake();
snake->breathe();
snake->crawl();
system("pause");
return 0;
}
snake->crawl(); tries to access crawl through a LivingThing*, without a v-table reference, LivingThing* cannot call Snake::crawl.
In your current example you could just change the LivingThing pointer to be a Snake pointer.
In a more complex situation:
If you know that the pointer you're calling crawl on points to an object that is infact a Snake then you can static_cast the pointer.
if(Snake* snake = static_cast<Snake*>(livingThing))
snake->crawl();
If you have no guarantee that the living thing is actually a Snake and you have rtti available then you can use dynamic_cast.
if(Snake* snake = dynamic_cast<Snake*>(livingThing))
snake->crawl();
When you upcast object to it's base type, you can only use methods which are declared in this base class. So if you don't want to declare crawl method in your base type, you've to downcast your object before using this method:
LivingThing *creature = new Snake();
creature->breathe();
if(Snake* snake = dynamic_cast<Snake*>(creature)) snake->crawl();

C++ : grandchild class has no implementation of virtual function of both child & parent class, program works

I was just revising the basic concepts of OOP and I ran across this. The program works but I can not understand why it works. I have a base class Vehicle and child class Car and Grandchild class TwoDoorCar. The code is given below:
class Vehicle {
private:
int wheels;
string make;
protected:
int protect;
public:
virtual ~Vehicle(){}
Vehicle(){
cout << "empty Vehicle constructor" << endl;
this->wheels = 0;
this->make = "";
this->protect = 0;
}
Vehicle(int wheel,string m){
cout << "parametrized Vehicle constructor" << endl;
this->wheels = wheel;
this->make = m;
this->protect = 0;
}
void ctest() const{ // read only function
cout << "ctest() called" << endl;
}
virtual void Drive() = 0;
const string& getMake() const {
return make;
}
void setMake(const string& make) {
this->make = make;
}
int getWheels() const {
return wheels;
}
void setWheels(int wheels) {
this->wheels = wheels;
}
};
class Car : virtual public Vehicle {
private:
int carNumber;
public:
virtual ~Car(){}
Car():Vehicle(){
cout << "empty car constructor" << endl;
carNumber = 0;
}
Car(int wheels, string make, int Number) : Vehicle(wheels,make){
cout << "Car's constructor called" << endl;
this->carNumber = Number;
}
Car(int wh, string m): Vehicle(wh, m){
this->carNumber = 0;
}
virtual void Drive(){
cout << "Car driven " << endl;
}
virtual void Drive(string p){
cout << "Over loaded function of Drive with string argument : " << p << endl;
}
void testProtect(){
cout << "Car::Protected member " << this->protect << endl;
}
};
class TwoDoorCar : public Car{
public:
virtual ~TwoDoorCar(){}
TwoDoorCar():Car(){
cout << "Empty two door car constructor" << endl;
}
TwoDoorCar(int wheels, string make, int reg) : Car(wheels,make,reg){
}
};
The pure virtual function Drive() is defined in the child class but not in the grandchild class. I tried using virtual in the child class, yet the program works with no function implementation of the Drive() function in the grandchild class.
I run with the following code
TwoDoorCar tdc1;
Vehicle * v3 = &tdc1;
v3->Drive();
The output of the program is
empty Vehicle constructor
empty car constructor
Empty two door car constructor
Car driven
Can anyone explain why there is no error here even though pure virtual and virtual are used in base and child class respectively?
Only pure virtual functions are required to be defined. virtual functions can be derived by inherited classes and does not require to be re-defined in inherited class.

Adding invariants in non virtual interface idiom

Suppose I have the following hierarchy using the NVI idiom :
class Base
{
public:
virtual ~Base() {}
void foo() { cout << "Base::foo" << endl; foo_impl(); }
private:
virtual void foo_impl() = 0;
};
class A : public Base
{
private:
virtual void foo_impl() { cout << "A::foo_impl" << endl; }
};
If at some point in the hierarchy I want to "add" invariants in the non virtual base method, what would be the best way to do so ?
One way would be to recurse the NVI idiom at the SpecialBase level :
class SpecialBase : public Base
{
private:
void foo_impl() { cout << "SpecialBase::foo" << endl; bar_impl(); }
virtual void bar_impl() = 0;
};
class B : public SpecialBase
{
private:
virtual void bar_impl() { cout << "B::bar_impl" << endl; }
};
But I don't really like this idea, since I don't want to add methods (with different names) for each derived bases I add to my hierarchy...
Another way is to have the following (which is not NVI) :
class Base
{
public:
virtual ~Base() {}
virtual void foo() { base_foo(); foo_impl(); }
protected:
void base_foo() { cout << "Base::foo" << endl; }
virtual void foo_impl() = 0;
};
class SpecialBase : public Base
{
public:
virtual void foo() { base_foo(); specialbase_foo(); foo_impl(); }
protected:
void specialbase_foo() { cout << "SpecialBase::foo" << endl; }
};
class B : public SpecialBase
{
private:
virtual void foo_impl() { cout << "B::foo_impl" << endl; }
};
Which in my opinion is less confusing since at any point a concrete class just has to implement the virtual method, while a derived base class can override the base (virtual) method if it chooses too.
Is there another cleaner way to achieve the same ?
EDIT:
I'm looking for a very general design pattern that could allow me to have the following kind of hierarchy :
Base <- A
<- B
<- SpecialBase <- C
<- D
<- VerySpecialBase <- E
<- StrangeBase <- F
Where each Base class can (and will override foo), whereas classes A-F will only need to reimplement foo_impl.
Note that just adding another optional customization virtual function (e.g bar_impl) won't help here, because it only allow for one extra layer of customization, where I could possibly need an infinite number.
In my understanding, NVI is a way to prevent/discourage adding invariants to the non-virtual base method, so the fact that you want to add invariants at this point suggests that NVI either isn't the pattern you are looking for at all, or you might want to restructure your design so that you do not need to add such invariants.
That being said an alternative to simply making your previously non-virtual interface virtual would be to employ the final keyword from C++11:
class Base
{
public:
virtual ~Base() {}
virtual void foo() { base_foo(); foo_impl(); }
protected:
void base_foo() { cout << "Base::foo" << endl; }
virtual void foo_impl() = 0;
};
class SpecialBase : public Base
{
public:
virtual void foo() final // note the use of 'final'
{ base_foo(); specialbase_foo(); foo_impl(); }
protected:
void specialbase_foo() { cout << "SpecialBase::foo" << endl; }
};
class B : public SpecialBase
{
private:
virtual void foo_impl() { cout << "B::foo_impl" << endl; }
};
Here NVI is not implemented by the class Base, but is implemented at the level of SpecialBase since classes derived from SpecialBase can no longer override the public interface (namely foo).
In this way we are saying that the public interface of Base is allowed to be overridden (invariants may be added, or even the entire function may be reimplemented), but the public interface of SpecialBase is not.
Personally I find that this can be useful in some limited cases, but most of the time I simply wanted a more complete interface in Base in the first place.
Ultimately I think it is more common to use Base to clearly define what points of customization are allowed:
class Base
{
public:
virtual ~Base() {}
virtual void foo() { base_foo(); bar_impl(); foo_impl(); }
protected:
void base_foo() { cout << "Base::foo" << endl; }
virtual void bar_impl() {} // bar_impl is an optional point of customization
// by default it does nothing
virtual void foo_impl() = 0; // foo_impl is not optional derived classes
// must implement foo_impl or else they will be abstract
};
class B : public Base
{
private:
virtual void bar_impl() { cout << "SpecialBase::foo" << endl; }
virtual void foo_impl() { cout << "B::foo_impl" << endl; }
};
Note that there is no longer a need for the SpecialBase class layer at all.
This post was suggested to me as similar to something I was browsing related to NVI the other day, hence the necro.
I would suggest adding a Check-Adding mechanism in the base class, so that derived classes can add requirements. This works in a very straightforward way as long as the requirements can be tested using the base class access functions, otherwise your special MyInvariant class has to dynamic_cast the base argument of doCheckInvariantOK() for the invariant to work.
edit: I understand 'invariant' to be along the lines of pre- and post-conditions of foo(), as in formal verfication. If you want to add functionality before and/or after base_foo(), what I think you're actually after, you can do it in an analogous fashion.
class Base
{
public:
virtual ~Base() {}
void foo()
{
cout << "Base::foo" << endl;
//Can use invariants as pre and/or postconditions for foo_impl
for(const std::unique_ptr<InvariantBase>& pInvariant : m_invariants)
{
//TODO cout << "Checking precondition " << pInvariant->GetDescription() << endl;
if(!pInvariant->CheckInvariantOK(*this))
{
//Error handling
}
}
foo_impl();
}
protected:
void AddInvariant(std::unique_ptr<InvariantBase>&& pInvariant)
{
m_invariants.push_back(std::move(pInvariant));
}
struct InvariantBase
{
bool CheckInvariantOK(const Base& base)
{
return doCheckInvariantOK(base);
}
private:
virtual bool doCheckInvariantOK(const Base& base) = 0;
};
private:
std::list<std::unique_ptr<InvariantBase>> m_invariants;
virtual void foo_impl() = 0;
};
class A : public Base
{
private:
virtual void foo_impl() { cout << "A::foo_impl" << endl; }
};
class SpecialBase : public Base
{
public:
SpecialBase()
: Base()
{
AddInvariant(std::unique_ptr<MyInvariant>(new MyInvariant() ) );
}
private:
void foo_impl() { cout << "SpecialBase::foo" << endl; bar_impl(); }
virtual void bar_impl() = 0;
struct MyInvariant : public InvariantBase
{
virtual bool doCheckInvariantOK(const Base& base) override
{
//TODO: special invariant code
}
};
};
class B : public SpecialBase
{
private:
virtual void bar_impl() { cout << "B::bar_impl" << endl; }
};