如何为现有对象填充接口?

时间:2019-03-01 10:53:35

标签: c++ c++11

我有一个界面:

struct result {
  virtual ~result() = 0;
  virtual auto getName() -> std::string = 0;

  protected:
    result() = default;
    result(const result &) = default;
    auto operator=(const result &) -> result & = default;
}

和实现:

struct abstract_result : public result {
  auto getName() -> std::string override;
  std::string m_name;
}

我当前在代码中使用abstract_result的实例,并由多种算法填充,但是我希望最终用户收到指向该接口的指针,以便隐藏实现。

如何将abstract_result的实例转换为std::unique_ptr<result>

2 个答案:

答案 0 :(得分:3)

abstract_result是-result(顺便说一句,您的命名似乎是错误的方法),因此指向abstract_result的指针是-指向result的指针。因此,您只需要构造unique_ptr,例如

auto x = unique_ptr<result>(new abstract_result());

如果实例在堆栈中,并且您担心unique_ptr尝试使用自动存储删除实例,则可以使用不执行任何操作的删除器,如

template <typename T>
struct no_deleter {
    void operator()(T*){}
};

abstract_result x;
std::unique_ptr<result> x_ptr{ &x, no_deleter<result>() };

但是,在那种情况下,我想知道为什么首先要使用unique_ptr。只要原始指针不拥有对象(使用指针的人不负责删除对象),就可以使用原始指针,而unique_ptr通常是拥有它所指向的对象的。

PS

我必须承认我不完全了解您的问题...

  

但我想将填充的abstract_result实例转换为   指向结果的指针

如上所述,指向abstract_result的指针已经(粗俗地说)指向result的指针。一个简单的例子:

abstract_result x;
result* pointer_to_result = &x;

答案 1 :(得分:2)

如果我对您的理解正确,那么您想要做的事情与@ user463035818所说的非常相似,但是具有填充的结构,即:

std::unique_ptr<result> pointer_to_result {&my_populated_abstract_result };

这很好,因为abstract_result是-result。但是如果您的my_populated_abstract_result不是动态分配的,那么您可能根本不想做。 std :: unique_ptr通常不适用于堆栈上的对象(例如局部变量)。如果my_populated_abstract_result是局部变量-根本不要放入unique_ptr (也不要放在std::shared_ptr中),也不要试图坚持一旦my_populated_abstract_result超出范围,便会进入它。

PS:

  • 将纯虚拟基类称为abstract_result,将具体类为foo_resultbar_resultbaz_result有意义吗?
  • 如果您确实有很多带有_result的名称,也许使用命名空间是个好主意吗?这样,您将拥有result::abstract(或result::base),然后是result::fooresult::barresult::baz