【发布时间】:2016-10-28 08:25:39
【问题描述】:
我有一堂课widget。
我有一个抽象类 base 与派生 derived_a、derived_b 等。
我希望widget 保存从base 派生的任意数量的对象,以便以后多态地使用它们。
我的第一次尝试是这样的:
#include <vector>
#include <ostream>
#include <iostream>
#include <memory>
class widget {
public:
explicit widget(std::vector<std::unique_ptr<base>>&& params) :
members {std::move (params)}
{
}
private:
std::vector<std::unique_ptr<base>> members;
};
会这样称呼:
std::vector<std::unique_ptr<base>> v;
v.push_back(std::move(std::make_unique<derived_a>()));
widget w (std::move(v));
但是,此解决方案过于冗长且对用户不友好,尤其是在提供多种类型时:
std::vector<std::unique_ptr<base>> v;
v.push_back(std::move(std::make_unique<derived_a>()));
v.push_back(std::move(std::make_unique<derived_b>()));
v.push_back(std::move(std::make_unique<derived_c>()));
v.push_back(std::move(std::make_unique<derived_a>()));
v.push_back(std::move(std::make_unique<derived_b>()));
v.push_back(std::move(std::make_unique<derived_c>()));
widget w {std::move(v)};
相反,我更喜欢使用
widget w {derived_a(),
derived_b(),
derived_c(),
derived_a(),
derived_b(),
derived_c()};
以便widget 提供一个右值列表,然后它可以将其转换为std::vector<unique_ptr<base>>。
我的印象是,这可以通过模板化 ctor 来实现,但是,尽管进行了密集的谷歌搜索,但我不知道如何准确地实现我的目标。
请注意,类模板解决方案看起来像这样:
widget<derived_a,
derived_b,
derived_c,
derived_a,
derived_b,
derived_c> w;
不受欢迎,因为我需要为一些派生提供参数。
【问题讨论】:
-
抱歉 - 我有一段时间没有考虑 OOP 问题...但是您不能通过使用工厂类来实现一些更简单的编码吗?
class wf { static std::unique_ptr<derived_a> make_a(/*maybe some args*/) { ... }; ... };然后widget w; w.visuals( { wf::make_a(); ... } )? -
只是为了“少”一点冗长。 AFAIK 你不需要
push_back中的move -
很好,我的工厂想法失败了。
std::unique<>似乎在处理抽象基类时遇到了问题。谁会猜到他们在内部尝试复制? :) -
@Hayt 是的,
std::move在使书面代码臃肿的同时一无所获。
标签: c++ c++11 templates polymorphism c++14