【发布时间】:2019-11-10 23:02:11
【问题描述】:
ControllerSender 是基类,有几个类是它的直接子类(本例中只有 BasicSender)并通过工厂函数 MidiControllers::AddSender 实例化。
指向实例化对象的指针以及其他信息存储在映射中。在 map 中构建信息的顺序是首先使用AddController 获取 key (id),并在 map 中放置一个新成员,默认为 Capabilities。然后AddOutputPtr 在Capabilities 中放置一个shared_ptr 到输出设备的键。最后AddSender 为从ControllerSender 派生的密钥创建一个新的发送者。失败的正是这第三步。
工厂函数抛出这个编译器错误:
binary '=': 没有找到使用 'std::unique_ptr
>' 类型的右侧操作数的运算符(或没有可接受的转换)和 [_Ty=BasicSender ]
失败的线是
controllers_.at(id).sender_ = std::make_unique<BasicSender>(ptr);
如果我将 BasicSender 更改为基类 (ControllerSender),则该行编译不会出错。我认为这个赋值应该自动向上转换指针,如Is unique_ptr<Derived> to unique_ptr<Base> up-casting automatic? 中所述。
我该如何解决这个问题?
#include <map>
#include <vector>
#include <JuceLibraryCode/JuceHeader.h>
class ControllerSender {
public:
ControllerSender(std::shared_ptr<juce::MidiOutput>& device) : device_(device) {}
private:
std::shared_ptr<juce::MidiOutput> device_{};
};
class BasicSender : ControllerSender {
public:
using ControllerSender::ControllerSender;
};
class MidiControllers {
public:
void AddController(const juce::MidiDeviceInfo& id)
{
controllers_.insert({id, Capabilities{}});
}
void AddOutputPtr(const juce::MidiDeviceInfo& id, std::shared_ptr<juce::MidiOutput>& device)
{
controllers_.at(id).device_ = device;
}
void AddSender(const juce::MidiDeviceInfo& id, std::string sender_name)
{
auto& ptr = controllers_.at(id).device_;
if (ptr) {
if (sender_name == "BasicSender") {
controllers_.at(id).sender_ = std::make_unique<BasicSender>(ptr);
}
}
}
private:
struct Capabilities {
std::shared_ptr<juce::MidiOutput> device_{nullptr};
std::unique_ptr<ControllerSender> sender_{nullptr};
};
struct IdentifierComp {
bool operator()(const juce::MidiDeviceInfo& lhs, const juce::MidiDeviceInfo& rhs) const
noexcept
{
return lhs.name < rhs.name || lhs.identifier < rhs.identifier;
}
};
std::map<juce::MidiDeviceInfo, Capabilities, IdentifierComp> controllers_;
};
【问题讨论】:
-
当
T派生自U时,可以将unique_ptr<T>分配给unique_ptr<U>。但这确实需要U有一个虚拟析构函数。您的基类ControllerSender没有。另外,您的BasicSender使用的是私有继承而不是公共继承,这是您真正想要的吗?
标签: c++ c++11 unique-ptr upcasting