简体   繁体   English

无法将派生的原始指针分配给基 unique_ptr

[英]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.本质上,我有一个基类 class 和一些派生类。

I also have a manager that uses a (smart) pointer to that base class.我还有一个管理器,它使用指向该基数 class 的(智能)指针。

And a Factory Method that returns the appropriate Derived object (although the signature returns a Base* ).以及一个返回适当 Derived object 的工厂方法(尽管签名返回一个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.我尝试使用unique_ptrmake_unique<raw pointer>() --> 它不适用于派生类,仅适用于基类。

I tried using unique_ptr and raw pointers --> conversion is not possible.我尝试使用unique_ptr和原始指针 --> 转换是不可能的。

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.我尝试使用原始指针(虽然我不想要这个)和原始指针 --> 它告诉我析构函数是在抽象的基础 object 上调用的。 How can you call a destructor when you haven't instantiated the object (since it's an abstract class)?如果您还没有实例化 object(因为它是一个抽象类),您怎么能调用析构函数呢? The compiler is contradicting itself!编译器自相矛盾!

Let's check the documentation for std::unique_ptr 's constructors .让我们检查std::unique_ptr构造函数的文档。 The signature of the relevant constructor:相关构造函数的签名:

explicit unique_ptr( pointer p ) noexcept; (2) (2)

The converting constructor that converts a raw pointer to a std::unique_ptr is explicit .将原始指针转换为std::unique_ptr的转换构造函数是explicit的。 Among other things, this means it cannot be used for copy initialization of the form除其他事项外,这意味着它不能用于表单的 复制初始化

std::unique_ptr<Info> info = InfoFactory::GetInfo();

Instead, you can use direct initialization :相反,您可以使用直接初始化

std::unique_ptr<Info> info{InfoFactory::GetInfo()};

Which will allow you to perform that conversion.这将允许您执行该转换。


While looking at this code, however, I notice that the local variable info in InfoManager::IsSomething is shadowing the class member variable InfoManager::info .但是,在查看这段代码时,我注意到InfoManager::IsSomething中的局部变量info隐藏了 class 成员变量InfoManager::info If you want to change an existing std::unique_ptr so that it's now managing a new raw pointer, you might want to use reset :如果您想更改现有的std::unique_ptr以便它现在管理一个新的原始指针,您可能需要使用reset

info.reset(InfoFactory::GetInfo());

Ok, so I did the following:好的,所以我做了以下事情:

  1. InfoFactory::GetInfo() now returns a std::unique_ptr<Info> , as indicated by Galik InfoFactory::GetInfo()现在返回一个std::unique_ptr<Info> ,如Galik 所示
  2. Added virtual ~Info() = default;添加virtual ~Info() = default; as indicated by Nathan Pierson正如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!感谢所有做出积极贡献的人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM