std :: shared_ptr类工厂C ++

时间:2014-09-18 02:41:34

标签: c++ inheritance c++11 shared-ptr factory-pattern

我们有一个基类......

class Node
{
   public:
      std::string Name;
      Node(){};
      ~Node(){};
}

过滤器节点的派生类。 过滤器是一个节点,除了它有一个< filterid'属性及其构造函数填充节点 .Name ='过滤器'。

class Filter: public Node
{
   public:
      int filterId;
      Filter() : Node()
      {
         Name="Filter";
      }
}

我有一个在传递字符串

时返回std::shared_ptr<Node>的ClassFactory

请在此链接后找到CodeProject上该工厂的代码。

http://www.codeproject.com/Articles/567242/AplusC-b-bplusObjectplusFactory

代码似乎实例化过滤器,但是,返回节点。即对象切片。

std::shared_ptr<Node> n = std::make_shared(Node);  // As expected, doesn't not have filter ID and node.Name is blank.
std::shared_ptr<Filter> f = std::make_shared(Filter);  // As expected, has filterID and node.Name is 'Filter'.

现在我想处理一个std :: shared_ptr(Node)数组,它实际上可能包含std :: shared_ptr(Filter),具体取决于工厂要求的类。

std::shared_ptr<Node> nf = std::make_shared(Filter);     // Error. Does not have filterId, but does have **Node**.Name='Filter'.

我甚至尝试过更简单的案例.....并且遇到了同样的问题。

Node n = Node();
Filter f = Filter();
Node nf =Filter();   // Error, nf does not have a filterID, but it's Name field is set to 'Filter'.

我在这里做错了什么? 节点是我所有派生类的基类。当我有一个接受节点的功能时,我应该能够发送一个过滤器并让filterId可用。

建议指针在这样的情况下提供帮助,但是shared_ptr是一个很有用的东西。

2 个答案:

答案 0 :(得分:1)

Node对衍生类可能定义的其他数据成员和函数没有任何了解。因此,您需要检索shared_ptr<Filter>才能访问filterId。使用std::dynamic_pointer_cast执行此操作。

std::shared_ptr<Node> n = ...
auto f = std::dynamic_pointer_cast<Filter>(n);

if(f) {
    // The managed object is a Filter
    std::cout << f->filter_id << '\n';
}

Live demo

如果您知道n始终包含Filter(或来自Filter的内容),则可以使用std::static_pointer_cast代替。

答案 1 :(得分:0)

如果您对基类有任何指针或引用方式,则只能访问基类API公开的内容。如果您想访问filterId,则需要:

  • 将其添加到基础界面(可能使用返回boost::optional<int>的函数,或者在可用时返回true,filterId对,否则例如false,0)或

    < / LI>
  • 看看你是否可以std::dynamic_pointer_castFilter类型,如果返回的指针在布尔上下文中是true,你可以用它来访问filterId }。