用于收集多态对象的API

时间:2020-06-08 14:05:59

标签: c++ c++11

假设我有一个多态对象的集合。我幼稚的示例实现将是这样的:

#include <iostream>
#include <memory>
#include <vector>

struct Parent{
    virtual void print() const {std::cout<<name <<"\n";}
    std::string name{"parent"};
};

struct ChildA:Parent{
    virtual void print() const {std::cout<<name <<descr<<"\n";}

    std::string name{"child A"};
    std::string descr{" is awesome"};
};

struct ChildB:Parent{
    virtual void print() const {std::cout<<name <<"\n";}
    std::string name{"child B"};
};

class Collection {
public:
   void print(){
       for (const auto& entry:data){
       entry->print();
       }
   }

  void add_data(std::unique_ptr<Parent> p){
    data.emplace_back(std::move(p));
  }

private:
  std::vector<std::unique_ptr<Parent>> data;
};

int main(){
Collection coll;
coll.add_data(std::make_unique<ChildA>(ChildA()));
coll.add_data(std::make_unique<ChildB>(ChildB()));
coll.print();
}

有没有更优雅的方式?我能以某种方式通过(const)参考吗?我真的不喜欢API中的make_unique。

作为解决方案,我提出了以下建议:

template <typename T>
void add_data(const T& d){
    data.emplace_back(std::make_unique<T>(d));
}

可以更自然地使用:

coll.add_data(ChildA())

一个相关的问题是包装器类的构造函数。也许:

class Wrapper{
public:

template <typename T>
Wrapper(const T& p):entry{std::make_unique<T>(p)}{}
template <typename T>
Wrapper(const T&& p):entry{std::make_unique<T>(p)}{}

void print(){
    entry->print();
    }

private:
std::unique_ptr<Parent> entry;
};

live code

这个问题似乎很普遍,所以我想问:什么是“最佳实践”解决方案?

0 个答案:

没有答案
相关问题