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; }
source share