是否可以编写C ++基类成员函数来实例化从中调用的任何派生类?

时间:2013-12-03 23:13:13

标签: c++ oop inheritance generic-programming

有没有办法只在基类中实现一个函数,该函数将返回从中调用它的任何派生类的实例?

3 个答案:

答案 0 :(得分:2)

template <class TDerived> class Base
{
    TDerived retInstance()
    {
        return TDerived();
    }
};

class Derived : Base<Derived>
{
    //class definition here
};

答案 1 :(得分:0)

如上所述,

  1. CRTP(奇怪的重复模板模式)

  2. 或Cloneable Pattern。


  3. 1。 CRTP

    查看 Liv on Coliru

    template <typename Derived>
    struct BaseImpl
    {
        // normal stuff
        int foo() const { return 42; }
    
        // CRTP stuff
        Derived make_new() const 
        {
            return Derived("test 123");
        }
    };
    
    #include <string>
    
    struct MyStruct : BaseImpl<MyStruct>
    {
        std::string value;
        MyStruct(std::string const& value) : value(value) {}
    };
    
    #include <iostream>
    
    int main()
    {
        MyStruct a("first");
        MyStruct b = a.make_new();
    
        std::cout << a.value << "\n"
                  << b.value << "\n";
    }
    

    打印

    first
    test 123
    

    2。可克隆模式:

    同时查看 Live on Coliru

    struct ICloneable
    {
        virtual const char* whoami() const = 0;
        virtual ICloneable* clone() const = 0;
    
        virtual ~ICloneable() throw() {}
    };
    
    #include <string>
    
    struct A : ICloneable
    {
        virtual const char* whoami() const { return "struct A"; }
        virtual ICloneable* clone() const { return new A; }
    };
    
    struct B : ICloneable
    {
        virtual const char* whoami() const { return "struct B"; }
        virtual ICloneable* clone() const { return new B; }
    };
    
    #include <iostream>
    #include <typeinfo>
    
    int main()
    {
        A a;
        B b;
    
        ICloneable* aclone = a.clone();
        ICloneable* bclone = b.clone();
    
        std::cout << typeid(*aclone).name() << "\n";
        std::cout << typeid(*bclone).name() << "\n";
    
        delete aclone;
        delete bclone;
    }
    

    打印(依赖于编译器):

    1A
    1B
    

答案 2 :(得分:0)

如果您选择的语言支持C++ code example返回类型,则可以执行与以下covariant类似的操作:

struct A {
    virtual A *make() = 0;
};

struct B : public A {
    B *make() override {
        return new B{};  
    }
};

虽然这不符合您在基类中定义一次的标准,但我认为值得一提。