C++ 当对象被创建为基类时,如何获取派生类型的共享_ptr?

C++ 当对象被创建为基类时,如何获取派生类型的共享_ptr?,c++,templates,inheritance,shared-ptr,C++,Templates,Inheritance,Shared Ptr,我正在尝试编写一个nodegraph库,可以在单个应用程序中重用它来实现几种具体的不同nodegraph类型。我有基类节点和端口。当节点请求时,会根据需要创建端口 我希望能够创建子类MyNode和MyPort,这些子类可以专门化Node和Port并向其添加功能,但仍然继承所有基本特性 我特别提到的问题是,我在Node类中使用std::make_shared来创建端口对象,但在MyNode对象中,我希望将该端口对象转换为MyPort对象 我在下面包含代码,试图具体地演示我现在遇到的问题,但我想知道

我正在尝试编写一个nodegraph库,可以在单个应用程序中重用它来实现几种具体的不同nodegraph类型。我有基类节点和端口。当节点请求时,会根据需要创建端口

我希望能够创建子类MyNode和MyPort,这些子类可以专门化Node和Port并向其添加功能,但仍然继承所有基本特性

我特别提到的问题是,我在Node类中使用std::make_shared来创建端口对象,但在MyNode对象中,我希望将该端口对象转换为MyPort对象

我在下面包含代码,试图具体地演示我现在遇到的问题,但我想知道我的继承方法是否不是一条正确的道路,因此我非常愿意接受关于如何构建基本/专用节点图库的其他想法

#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;
}
#包括
#包括
#包括
使用名称空间std;
类端口{
公众:
端口(字符串名称):m_名称(名称){}
虚拟~Port(){}
字符串getName(){return m_name;}
私人:
字符串m_name;
};
类节点{
公众:
共享\u ptr getPort(字符串端口名)
{
返回make_shared(端口名);
}
};
MyPort类:公共端口{
公众:
MyPort(字符串名称):端口(名称){}
虚拟~MyPort(){}
字符串getLongName(){return getName()+“_LONG”;}
};
类MyNode:公共节点{
公众:
共享\u ptr getPort(字符串端口名)
{
shared_ptr tmpPort=Node::getPort(端口名);
返回动态指针转换(tmpPort);
}
};
int
main(int argc,const char*argv[])
{
MyNode节点;
shared_ptr port=node.getPort(“Taco”);
如果(端口==nullptr){

cout无法将派生类型的共享\u ptr获取到基类对象

为了向特定对象获取特定类型的共享ptr,该对象实际上必须是该类型。但在本例中,它不是。该对象是
端口
-它不是,也永远不会是
MyPort


您首先需要确保创建一个
MyPort
。一种方法是添加一个
createPort
函数。
Node::createPort
然后将创建一个新的
端口
,但您可以在
MyNode
中覆盖它,从而创建一个
MyPort
。或者,您可以覆盖
getPort
e> .

只需更新
MyNode::getPort
的定义,如下所示

shared_ptr<MyPort> getPort(string portName)
{
    return make_shared<MyPort>(portName);
}
shared\ptr getPort(字符串端口名)
{
返回make_shared(端口名);
}

强制转换不会更改基础对象的类型。如果您想要获得
MyPort
对象,您需要立即创建它。您可以使用Factory模式进行创建。我个人得出的结论是,有效地处理不同的图形表示需要通用编程。有一个看看Boost图库,看看它是如何完成的。@实际上,C++中的DITEMARK朱鹭确实改变了对象的类型,但是铸造一个<代码> SyddypTr>代码>不会改变它指向的对象的类型。@ ImibIs:在任何条件下,C++中的一个转换都不会损坏被铸造的对象的类型!(当强制转换目标类型恰好是值类型时)但原始对象的类型保持不变。指针或引用强制转换仅更改对象通过的实体的类型(在指针强制转换的情况下返回相应的临时对象)..和
dynamic_cast
验证对象是否确实匹配(对于其他类型的强制转换,您需要知道是这样的;如果不是这样,您将获得未定义的行为)。