0

I have an archi like that:

namespace nts {

   class IComponent
   {
   };

   class AbsComponent : public IComponent
   {
   };

   class cInput : public AbsComponent
   {
   };

}

I can't figure out how to cast a cInput as a std::unique_ptr < nts::IComponent > i tried like this with C-style cast:

std::unique_ptr<nts::IComponent> createInput(const std::string &val) noexcept
  {
        std::unique_ptr<nts::IComponent> component = (std::unique_ptr<nts::IComponent>)new nts::cInput(val));
        return (component);
  }

How could i cast this ?

1 Answers1

1

Just do:

std::unique_ptr<nts::IComponent> component = std::make_unique<nts::cInput>(val);

Also, you probably meant:

return component;

instead of:

return (val);

But you can just do:

return std::make_unique<nts::cInput>(val);

instead of the two lines.

EDIT:

std::make_unique is available from C++14, if you're using an older version, strongly consider updating, or you can do:

std::unique_ptr<nts::IComponent> component = std::unique_ptr<nts::cInput>(new nts::cInput(val));

or

return std::unique_ptr<nts::cInput>(new nts::cInput(val));
DeducibleSteak
  • 1,398
  • 11
  • 23
  • I think this doesnt create a new object nts::cInput, how could it be without invoking the constructor or using the "new" keyword ? – freeinternet Feb 28 '20 at 01:57
  • 1
    https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique std::make_unique "Constructs an object of type T and wraps it in a std::unique_ptr." It allocates the memory and calls the constructor for you, and does it in an exception safe way. – DeducibleSteak Feb 28 '20 at 01:58
  • it seems my function can't find the function, because i got a "no member name 'make_unique' in namespace 'std'" – freeinternet Feb 28 '20 at 02:01
  • @freeinternet - What C++ standard are you using? – Stephen Newell Feb 28 '20 at 02:06
  • not sure about that but with the update version (the 2) i got a : no viable conversion from 'unique_ptr' to 'unique_ptr' – freeinternet Feb 28 '20 at 02:17
  • It should work, have a look here: https://godbolt.org/z/gTnywE Are you sure you have included the needed headers and your inheritance is as you've described? – DeducibleSteak Feb 28 '20 at 02:22
  • i got this: https://i.imgur.com/agXH0w3.png for return (std::make_unique(val)); – freeinternet Feb 28 '20 at 02:32
  • Again, it should work, see here: https://godbolt.org/z/PBPDqp Are you _SURE_ your inheritance hierarchy is as you've said? – DeducibleSteak Feb 28 '20 at 02:36
  • @freeinternet A `unique_ptr` *can* be assigned to a `unique_ptr`, but only if `nts::cInput*` is implicitly convertible to `nts::IComponent*`, ie `nts::cInput` derives from `nts::IComponent`, which is true in the code provided in your question, but if it is not working in your real code, then your real code does not match your question's code. – Remy Lebeau Feb 28 '20 at 02:39
  • I'm 100% sure for the hierarchy, and this code output wiht g++ this: https://i.imgur.com/T5iPBbg.png, also IComponent is an interface, and AbsComponent an abstract classes. – freeinternet Feb 28 '20 at 02:47
  • Can you copy & paste here the class & inheritance definitions you have, just to confirm? Just the class names/inheritance, not the bodies/members, no need for that. – DeducibleSteak Feb 28 '20 at 02:50
  • You said you have `class cInput : public AbsComponent`, but in reality you have `class cInput : AbsComponent`. If you want this to work, you will have to inherit from `AbsComponent` publicly. If you don't, std::unique_ptr has no way of knowing that it is allowed to cast `cInput*` to `AbsComponent*`: https://stackoverflow.com/questions/860339/difference-between-private-public-and-protected-inheritance (if you are not aware, class inheritance is private by default, so you need to explicitly ask for it to be public) – DeducibleSteak Feb 28 '20 at 03:01
  • thank you very much, making huge mistakes as i'm tired!! – freeinternet Feb 28 '20 at 03:06