Recursive virtual call not working as it should?

Viewed 61

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... ?

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) };
Related