繁体   English   中英

如何使用CRTP和多继承C ++转发构造函数

[英]How to forward constructors with CRTP and multiple inheritance C++

我最近在c ++ 11中使用CRTP来使用协方差来克隆对象,我发现了这个: https//www.fluentcpp.com/2017/09/12/how-to-return-a-smart -pointer-and-use-covariance /帖子清晰,在某种程度上有效。 帖子没有说的是如何在构造函数中使用参数。 我使用Base :: Base获得虚拟技巧,但它强制用户在实例化叶类时明确地调用基础构造函数。 如果你正在寻找像钻石继承这样的东西,这只是想要的。

虽然,在更常见的情况下,当你有几个级别的继承时,你有类似的东西:抽象A - >抽象B - >抽象C - >具体D.我明白为什么只有叶子类应该是可实例化的。 但是在每个级别,构造函数越来越具体,并且我链接的CRTP设计示例,我不知道如何做到这一点。

在下文中,我想到了只有一个基类的简化:

// Virtual and abstract tricks
template <typename Base>
class Virtual : virtual public Base
{
public:
    using Base::Base;
};
template <typename Object>
class Abstract
{
};

// General CRTP : Inheritance + implementation of clone function
template <typename Object, typename Base=void>
class Clone : public Base
{
public:
    virtual ~Clone() =default;
    std::unique_ptr<Object> clone() const {
        return std::unique_ptr<Object>(static_cast<Object *>(this->copy()));
    }
private:
    virtual Clone * copy() const override {
        return new Object(static_cast<const Object &>(*this));
    }
};

// Specialization : Inheritance + an pure cloning function
template <typename Object>
class Clone<Abstract<Object>>
{
public:
    virtual ~Clone() =default;
    std::unique_ptr<Object> clone() const {
        return std::unique_ptr<Object>(static_cast<Object *>(this->copy()));
    }
private:
    virtual Clone *copy() const =0;
};

关于我的测试课程:

class TestB0 : public Clone<Abstract<TestB0>>
{
public:
    TestB0() : B0(new int(0)) {cout<<"crea B0 vide"<<endl;}
    TestB0(int xB0) : B0(new int(xB0)) {cout<<"crea B0 "<<xB0<<" : "<<*B0<<endl;}
    TestB0(const TestB0 &t) : B0(new int(*t.B0)) {cout<<"copy B0 "<<*B0<<endl;}
    virtual ~TestB0() {delete B0;}
    void setB0(int xB0) {*B0=xB0;}
    int getB0() {return *B0;}
private:
    int *B0;
};

class TestB1 : public Clone<TestB1, TestB0>
{
public:
    TestB1() : B1(new int(0)) {cout<<"crea B1 vide"<<endl;}
    TestB1(int xB0=11, int xB1=20) : B1(new int(xB1)) {cout<<"crea B1 "<<xB0<<" "<<xB1<<" : "<<getB0()<<" "<<*B1<<endl;}
    TestB1(const TestB1 &t) : B1(new int(*t.B1)) {cout<<"copy B1 "<<getB0()<<" "<<*B1<<endl;}
    virtual ~TestB1() {delete B1;}
    void setB1(int xB1) {*B1=xB1;}
    int getB1() {return *B1;}
private:
    int *B1;
};

当我实例化TestB1时,我无法访问TestB0的构造函数。 我可以使用虚拟技巧来做到这一点:

class TestB1 : public Clone<TestB1, Virtual<TestB0>>

但是当我这样做时,我必须明确地调用叶类中的构造函数。 当我只有一个级别的继承时,这不是问题。 我想是在我有更多的时候。

我无法找到一种方法让整个事情以优雅的方式运作。 有没有办法在不使用虚拟基础的情况下初始化基类? 通常在不使用CRTP时完成。

谢谢你的冬天。

作为评论:我正在为我想要从时间执行的角度优化的库创建多态类(所以没有虚拟表)。 我只能使用c ++ 11,所以使用包扩展的声明将不会像在c ++ 17中那样工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM