1

I have a class where its constructor takes an rvalue reference to a temporary object


class Lich: public Player  {
    protected:
        int mana;
        Spell spell;
    public:
        Lich(int mana,int health, int defense,Spell&& spell) : spell(spell), mana(mana), Player(health,defense)  {}
        void cast_spell(Player &target);
};

So far, the constructor of Lich is set to take an rvalue using spell(spell), and since spell is an rvalue, it should be that Spell(Spell&& spell) is the constructor that gets called.

But to my surprise, the copy constructor get's called, and I don't know why


Spell::Spell(Spell&& Spell) noexcept {
    std::cout << "move_constructed" << std::endl;
    this->cast_time=Spell.cast_time;
    this->mp_cost=Spell.mp_cost;
    this->damage=Spell.damage;
}

Spell::Spell(Spell& Spell)  {
    std::cout << "copy_constructed" << std::endl;
    this->cast_time=Spell.cast_time;
    this->mp_cost=Spell.mp_cost;
    this->damage=Spell.damage;
}

int main()  {
    Lich Arch_Lich(0,0,0,AOE_Spell(0,0,0,0));//AOE_Spell is a subclass from Spell
}

Can anyone explain why is does the compiler choose the copy constructor instead?(-std=c++11 standart used)

JohnAth
  • 11
  • 1
  • [What is object slicing?](https://stackoverflow.com/questions/274626/what-is-object-slicing) Your code will not behave as expected. Assigning a `AOE_Spell` to `Spell` object will "slice off" the extra stuff `AOE_Spell` adds. – François Andrieux Dec 02 '20 at 16:08
  • `Spell spell;` means the Lich member variable is not playing nice with polymorphism. – Eljay Dec 02 '20 at 16:10
  • A (named) `rvalue reference` is an `lvalue`. Isn't C++ great. – Mike Vine Dec 02 '20 at 16:12
  • See https://stackoverflow.com/questions/28483250/rvalue-reference-is-treated-as-an-lvalue – Mike Vine Dec 02 '20 at 16:13
  • Thanks a lot, I hadn't noticed this about Object Slicing, and the answer about named rvalues solved my issue and greatly hepled me. – JohnAth Dec 02 '20 at 16:22

0 Answers0