我正在尝试编写一个nodegraph库,可以重复使用它来在单个应用程序中实现几个具体的不同nodegraph类型。我有基类Node和Port。当节点请求时,按需创建端口。
我希望能够创建可以专门化并向Node和Port添加功能的子类MyNode和MyPort,但仍继承所有基本功能。
我特别指出的问题是我在Node类中使用std :: make_shared来创建Port对象,但是在MyNode对象中我希望将Port对象强制转换为MyPort对象。
我包括下面的代码,试着具体地说明我现在遇到的问题,但我想知道我的继承方法是不是正确的尝试下去的道路,所以我是对于如何构建我的基础/专用nodegraph库的方法非常开放。
#include <memory>
#include <string>
#include <iostream>
using namespace std;
class Port {
public:
Port(string name) : m_name(name) {}
virtual ~Port() {}
string getName() { return m_name; }
private:
string m_name;
};
class Node {
public:
shared_ptr<Port> getPort(string portName)
{
return make_shared<Port>(portName);
}
};
class MyPort : public Port {
public:
MyPort(string name) : Port(name) {}
virtual ~MyPort() {}
string getLongName() { return getName()+"_LONG"; }
};
class MyNode : public Node {
public:
shared_ptr<MyPort> getPort(string portName)
{
shared_ptr<Port> tmpPort = Node::getPort(portName);
return dynamic_pointer_cast<MyPort>(tmpPort);
}
};
int
main (int argc, const char *argv[])
{
MyNode node;
shared_ptr<MyPort> port = node.getPort("Taco");
if (port == nullptr) {
cout << "null ptr" << std::endl;
} else {
cout << port->getName() << endl;
cout << port->getLongName() << endl;
}
return 1;
}
当我运行此代码时,dynamic_pointer_cast返回一个nullptr。
答案 0 :(得分:2)
您无法将派生类型的shared_ptr获取到基类对象。
为了将特定类型的shared_ptr获取到某个对象,该对象必须实际上属于该类型。但在这种情况下,它不是。该对象是Port
- 它不是,也绝不会是MyPort
。
您需要确保首先创建MyPort
。一种方法是添加createPort
函数。然后,Node::createPort
会创建一个新的Port
,但您可以在MyNode
中覆盖它,以便创建MyPort
。或者,您可以覆盖getPort
。
答案 1 :(得分:0)
只需更新MyNode::getPort
的定义,如下所示。
shared_ptr<MyPort> getPort(string portName)
{
return make_shared<MyPort>(portName);
}