Returns unique_ptr to a polymorphic type

I try to be safer by returning unique_ptr from several of my methods, and not from the original pointer. However, I'm a little confused when it comes to returning a unique pointer to a polymorphic type.

How to return a unique pointer to a base class type that points to a type of a derived class?

Also, as a minor question of less relevance: am I creating my derived class from a base class using the move constructor?

Here is my minimal example:

// Standard Includes #include <exception> #include <memory> #include <string> #include <sstream> //-------------------------------------------------------------------------------------------------- class BaseResult { public: std::string m_x; virtual ~BaseResult() {}; }; class DerivedResult : public BaseResult { public: int m_y; DerivedResult() : BaseResult() {} DerivedResult(const DerivedResult & rhs) : BaseResult(rhs) , m_y (rhs.m_y) {} DerivedResult(DerivedResult && rhs) : BaseResult(std::move(rhs)) , m_y(rhs.m_y) {} DerivedResult(BaseResult && rhs) : BaseResult(std::move(rhs)) , m_y() { } ~DerivedResult() {} }; class BaseCalc { public: virtual ~BaseCalc() {} virtual std::unique_ptr<BaseResult> Calc() const { std::unique_ptr<BaseResult> result(new BaseResult); result->m_x = "Base Calced"; return result; } }; class DerivedCalc : public BaseCalc { public: virtual ~DerivedCalc() {} virtual std::unique_ptr<BaseResult> Calc() const { // I need to rely on the base calculations to get the fields relevant to the base std::unique_ptr<BaseResult> baseResult = BaseCalc::Calc(); // However, I want to perform my addtional calculation relevant to derived, here. std::unique_ptr<DerivedResult> result(new DerivedResult(std::move(*baseResult))); result->m_y = 2; /* Results in error return result; */ return std::move(result); // Is this how we do it? } }; //-------------------------------------------------------------------------------------------------- int main() { DerivedCalc calculator; std::unique_ptr<BaseResult> temp = calculator.Calc(); // Cast - Got this part from https://stackoverflow.com/questions/21174593/ std::unique_ptr<DerivedResult> actualResult; if (DerivedResult * cast = dynamic_cast<DerivedResult *>(temp.get())) { actualResult = std::unique_ptr<DerivedResult>(cast, std::move(temp.get_deleter())); temp.release(); } else { std::exception("Failed to cast to DerivedResult"); } std::string x = actualResult->m_x; int y = actualResult->m_y; return 0; } 
+5
source share
1 answer

Answering your first question: "How to return a unique pointer to the type of the base class that points to the type of the derived class?" (note that std :: make_unique requires C ++ 14):

 class DerivedCalc : public BaseCalc { public: virtual ~DerivedCalc() {} virtual std::unique_ptr<BaseResult> Calc() const { // I need to rely on the base calculations to get the fields relevant to the base std::unique_ptr<BaseResult> baseResult = BaseCalc::Calc(); // However, I want to perform my addtional calculation relevant to derived, here. std::unique_ptr<BaseResult> result(std::make_unique<DerivedResult>(std::move(*baseResult))); DerivedResult& derived = static_cast<DerivedResult&>(*result); derived.m_y = 2; return result; } }; 

For your second question: “Am I creating my derived class from the base class using the move constructor correctly?”, Your version works, but you can also move the derived data field for optimal performance:

 class DerivedResult : public BaseResult { ... DerivedResult(DerivedResult && rhs) : BaseResult(std::move(rhs)) , m_y(std::move(rhs.m_y)) {} ... }; 
0
source

Source: https://habr.com/ru/post/1268713/


All Articles