C++ 是否可以创建非虚拟的创建方法

C++ 是否可以创建非虚拟的创建方法,c++,c++11,rtti,C++,C++11,Rtti,方法创建适当动态类型的对象,但我不想使用样板代码 有可能吗 std::shared_ptr<Base> create() const; std::shared_ptr create()常量; 静态绑定,但在内部找到正确的类型并使用默认构造函数创建对象?可能使用C++11。函数的create()应该是静态的,因为您还没有实例。但是如果没有参数,你就不能做你想做的事。。。当然,除非您使用模板,否则: std::shared_ptr<Base> create() const

方法创建适当动态类型的对象,但我不想使用样板代码

有可能吗

std::shared_ptr<Base> create() const;
std::shared_ptr create()常量;
静态绑定,但在内部找到正确的类型并使用默认构造函数创建对象?可能使用C++11。

函数的
create()
应该是静态的,因为您还没有实例。但是如果没有参数,你就不能做你想做的事。。。当然,除非您使用模板,否则:

std::shared_ptr<Base> create() const;
类基
{
公众:
模板
静态std::shared_ptr create()常量
{
返回std::共享(新T);
}
};
然后这样使用:

class Base
{
public:
    template<typename T>
    static std::shared_ptr<Base> create() const
    {
        return std::shared<Base>(new T);
    }
};
std::shared_ptr ptr(Base::create());
或者,如果您愿意:

std::shared_ptr<Base> ptr(Base::create<Foo>());
std::shared_ptr ptr(Foo::create());

理想情况下,您有一个静态的
create()
函数,也可能有一个非静态的
函数。有一种聪明的方法可以做到这一点

  • 定义一个
    SuperBase
    类。它需要一个虚拟析构函数和一个纯虚拟的
    create()
    函数。对于正常的后期绑定OOP行为,您将使用指向此类的指针/引用

  • 定义从
    SuperBase
    继承的
    Base
    类模板
    Base
    的模板参数将是
    派生类的类型
    Base
    还将有一个traits类模板,其中包含一个名为
    create()
    的静态函数。此静态
    create()
    函数将使用
    new
    创建默认对象。使用trait的
    create()
    函数,
    Base
    将定义
    static\u create()
    和纯虚拟
    SuperBase::create()
    函数

  • 通过从
    Base
    继承来实现
    派生的

  • 完成此操作后,如果知道正在使用派生类型,则可以编写
    derived::create()
    以静态方式创建一个新类型。如果没有,则始终可以使用实例的
    create()
    方法。多态性没有被破坏,因为
    SuperBase
    将具有您需要/想要的多态接口--
    Base
    只是一个辅助类,它自动定义
    static\u create()
    create()
    函数,因此您通常不会直接使用
    Base

    示例代码如下所示:

    std::shared_ptr<Base> ptr(Foo::create<Foo>());
    
    #包括
    #包括
    类超基
    {
    公众:
    virtual~SuperBase()=默认值;
    虚拟std::shared_ptr create()const=0;
    };
    模板
    结构基特征
    {
    静态T*create()
    {
    返回新的T;
    }
    };
    模板
    类基:公共超基
    {
    公众:
    //定义一个静态工厂函数。。。
    静态标准::共享\u ptr静态\u创建()
    {
    返回std::shared_ptr{Traits::create()};
    }
    //定义纯虚拟实现。。。
    std::shared_ptr create()常量重写
    {
    返回static_create();
    }
    };
    派生类:公共基
    {
    };
    int main()
    {
    auto newone=Derived::static_create();//类型known@compile time
    auto-anotherone=newone->create();//后期绑定;类型未知@编译时
    }
    
    A模板<代码>模板std::shared_ptr create()const{return new T();};p=create()。也许您可以提供一个如何使用它的示例?从总体上看,我正在尝试创建一个函数,该函数接受字符串形式的类名,并返回具有适当动态类型的std::shared_ptr。我想使用一个静态std::map来实现这一点object@Martin:对于您的用例,静态绑定不是选项。您需要一个虚拟调用或一个函数指针。@MartinDrozdik:只是风格问题,您的函数应该返回一个
    唯一的\u ptr
    ,因为它还没有被共享。谢谢!实际上我有一个例子。我有一个std::shared_ptr对象,它指向一个可能与Base不同的动态类型的对象。使用这个指针,我想请求一个合适的动态类型的默认构造样本。虽然这个答案不是我想要的,但我相信Ben Voigt,这是不可能的。我会照你说的做。马丁:我认为这个答案对你毫无帮助。如果知道要创建的类型,那么可以轻松创建共享的\u ptr——为什么要调用函数?即使使用该函数,也需要指定两种类型:before::create和template参数。啊,因为它是不需要的!我认为,当除了抽象基类之外,您不知道任何类型时,您也需要处理一般情况——对于这种情况,这个答案(分别)没有什么用处。例如,如何使用迭代器调用create()以列出?谢谢!我欣赏你的方法!
    std::shared_ptr<Base> ptr(Foo::create<Foo>());
    
    #include <memory>
    #include <iostream>
    
    class SuperBase
    {
      public:
        virtual ~SuperBase() = default;
        virtual std::shared_ptr<SuperBase> create() const = 0;
    };
    
    template <typename T>
    struct Base_Traits
    {
      static T* create()
      {
        return new T;
      }
    };
    
    template <typename Derived, typename Traits=Base_Traits<Derived>>
    class Base : public SuperBase
    {
      public:   
        // Define a static factory function...
        static std::shared_ptr<SuperBase> static_create()
        {
          return std::shared_ptr<SuperBase>{Traits::create()};
        }
    
        // Define pure virtual implementation...
        std::shared_ptr<SuperBase> create() const override
        {
          return static_create();
        }
    };
    
    class Derived : public Base<Derived>
    {
    };
    
    int main()
    {
      auto newone = Derived::static_create();  // Type known @ compile time
      auto anotherone = newone->create();      // Late binding; type not known @ compile time
    }