我们有一个基类......
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是一个很有用的东西。
答案 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';
}
如果您知道n
始终包含Filter
(或来自Filter
的内容),则可以使用std::static_pointer_cast
代替。
答案 1 :(得分:0)
如果您对基类有任何指针或引用方式,则只能访问基类API公开的内容。如果您想访问filterId
,则需要:
将其添加到基础界面(可能使用返回boost::optional<int>
的函数,或者在可用时返回true,filterId
对,否则例如false,0
)或
看看你是否可以std::dynamic_pointer_cast
到Filter
类型,如果返回的指针在布尔上下文中是true
,你可以用它来访问filterId
}。