Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive virtual call not working as it should?

Tags:

c++

recursion

I have this code:

#include <iostream>
#include <string>
using namespace std;

struct Flower
{
    virtual string str() = 0;
};

struct Rose : Flower
{
    string str() override { return "A rose"; }
};

struct RedFlower : Flower
{
    Flower& flower;
    RedFlower(Flower& flower) : flower{ flower } {}
    string str() override { return flower.str() + " that is red"; }
};

int main()
{
    Rose rose;
    RedFlower red_rose{ rose };
    RedFlower red_red_rose{ red_rose };
    RedFlower red_red_red_rose{ red_red_rose };
    cout << rose.str() << endl;
    cout << red_rose.str() << endl;
    cout << red_red_rose.str() << endl;
    cout << red_red_red_rose.str() << endl;
}

It prints out

A rose
A rose that is red
A rose that is red
A rose that is red

Shouldn't it print out

A rose
A rose that is red
A rose that is red that is red
A rose that is red that is red that is red

??? Why is it not printing out what it should? Does the compiler optimise away the calls or is the class hierarchy lost along the away? I don't seem to pin point what exactly it is that I'm missing. I know something must be wrong with my code. I believe dynamic polymorphism is lost somewhere in the call stack... ?

like image 675
Saitama10000 Avatar asked Oct 15 '22 00:10

Saitama10000


1 Answers

the problem here is, that the compiler automatically generates a copy- constructor with the following signature:

RedFlower(RedFlower const &)

That constructor is being called instead of your custom one. One solution is to add an explicit cast to Flower &:

Rose rose;
RedFlower red_rose{ rose };
RedFlower red_red_rose{ static_cast<Flower &>(red_rose) };
RedFlower red_red_red_rose{ static_cast<Flower&>(red_red_rose) };
like image 139
churill Avatar answered Nov 15 '22 11:11

churill