c++pointersinheritancesmart-pointersvirtual-inheritance

Cannot assign derived raw pointer to base unique_ptr


I have some code that looks something this:

class Info {
  public:
    virtual bool IsHere() = 0;
    virtual std::wstring GetStr() = 0;
};

class WindowsInfo : public Info {
  public:
    virtual std::wstring GetAnotherStr() = 0;
    bool IsHere() override;
};

class AdvancedWindowsInfo : public WindowsInfo {
  public:
    AdvancedWindowsInfo() {}
    ~AdvancedWindowsInfo() {}

    std::wstring GetAnotherStr() override;
    std::wstring GetStr() override;
};
  
class InfoFactory {
  public:
    static Info* GetInfo();
};
  
class InfoManager {
  public:
    InfoManager();
    //~InfoManager();

    bool IsSomething();

  private:
    std::unique_ptr<Info> info;
};
  
InfoManager::InfoManager() {
  #if WIN
    info = std::make_unique<WindowsInfo>();
  #else  // currently no implementation Linux
    info = nullptr;
  #endif
}
  
bool InfoManager::IsSomething() {
    std::unique_ptr<Info> info = InfoFactory::GetInfo();

    return info && info->IsHere();
}
  
Info* InfoFactory::GetInfo() {
  #if IS_WINDOWS
    return new AdvancedWindowsInfo();
  #else
    return nullptr;
  #endif
}

The entire code is too large (and confidential) to post here, but this snippet sums it up pretty well.

Essentially, I have a base class and some derived classes.

I also have a manager that uses a (smart) pointer to that base class.

And a Factory Method that returns the appropriate Derived object (although the signature returns a Base*).

Unfortunately, I can't get the the assignment (via the Factory Method) to work. I've tried multiple approaches but nothing works.

I tried using unique_ptr and make_unique<raw pointer>() --> it doesn't work with derived classes, only base.

I tried using unique_ptr and raw pointers --> conversion is not possible.

I tried using raw pointers (although I don't want this) and raw pointers --> it tells me that the destructor is called on the base object which is abstract. How can you call a destructor when you haven't instantiated the object (since it's an abstract class)? The compiler is contradicting itself!


Solution

  • Ok, so I did the following:

    1. InfoFactory::GetInfo() now returns a std::unique_ptr<Info>, as indicated by Galik
    2. Added virtual ~Info() = default; as indicated by Nathan Pierson

    Now everything seems to be working ok. For now, I will the question unanswered as I still need to run some tests and double check some things, but basically it seems to be ok.

    Thank you to everyone who made positive contibutions!