0

I have a simple structure of abstract class Animal and a class Dog derived from it. I want to keep different Animals in Cage using a pointer to Animal. I would like to be able to create a Dog inside of a Cage constructor but it creates a temporary object which I can't point to:

class Animal
{
public:
    Animal() {}
    virtual ~Animal() {}
};

class Dog: public Animal
{
public:
    ~Dog() {}
};

class Cage
{
public:
    const Animal* animal;
    Cage(Animal *anim): animal(anim) {}
};

int main()
{
    Dog doggy;
    Cage cage(&doggy); //works fine

    Cage new_cage(&Dog()); //error: taking address of temporary [-fpermissive]|
}

Is there any way to change the code, e.g. Cage's constructor, so that the object created in it's constructor would be non-temporary?

EDIT: It seems like it could be done using dynamic allocation but this question was marked as a duplicate of this question

Why lifetime of temporary doesn't extend till lifetime of enclosing object? , although it's a different question. I asked for any way to make that happen and not for extending a lifetime of a temporary. I would be grateful to πάντα ῥεῖ if he could explain how my question has an answer in this one's answers.

Elgirhath
  • 409
  • 1
  • 7
  • 15
  • You're not creating any objects in `Cage`'s constructor. – melpomene Jul 29 '18 at 21:18
  • You need to dynamically allocate the `Animal`. – eesiraed Jul 29 '18 at 21:19
  • @FeiXiang well that is not necessary either, the "works fine" version is fine – M.M Jul 29 '18 at 21:33
  • @M.M I assumed the OP wanted the `Cage` object to take ownership of the `Animal`. – eesiraed Jul 29 '18 at 21:39
  • It is fine, although having more complex hierarchy i would rather not create every single object this way as the would be clear enough. – Elgirhath Jul 29 '18 at 21:41
  • @FeiXiang that's indeed what I wanted. I don't need to have a variable `doggy` like here. Much better would be, if I could get into all the `Animal`s by choosing the right `Cage` and accessing an `Animal` from it – Elgirhath Jul 29 '18 at 21:44
  • 1
    You could use `std::unique_ptr` for the `Animal` pointer member of `Cage`. This would allow `Cage` to take ownership of the `Animal`. – zett42 Jul 29 '18 at 21:47
  • @zett42 how would I do that? I need the object to keep it's type of `Dog` so I can't call `new Animal(anim)` in a constructor – Elgirhath Jul 29 '18 at 22:21
  • 2
    Have the constructor take an `Animal` pointer and pass it to the constructor of the `std::unique_ptr` member in the constructor member initialization list. The constructor would look like `Cage(Animal *anim) : animal(anim) {}`. Now you can do `Cage cage(new Dog)`. – eesiraed Jul 30 '18 at 00:50
  • I would let the constructor take a `std::unique_ptr` parameter, to make it clear that ownership is transfered. A raw pointer parameter would not tell you that. Sure, you could document that, but self-documenting code is much better. [Live demo at Coliru](http://coliru.stacked-crooked.com/a/7d34d73b56525788). – zett42 Jul 30 '18 at 20:14

0 Answers0