每个派生类的复制构造函数

Copy constructor for every derived class

提问人:prestokeys 提问时间:5/3/2022 更新时间:5/4/2022 访问量:106

问:

请考虑以下代码。我希望该函数无需在每个具体派生类型中定义复制构造函数即可工作。 只有当它不是抽象的,但它是抽象的时,它才能以所示的方式在中间类中完成。那么在这种情况下,我该如何让它工作呢?convertT(const Base&)BaseCRTP<T>

struct Base {
    virtual void foo() = 0;
};

template <typename T>
struct CRTP : virtual Base {
    CRTP (const Base& base) : Base(base) { }
    CRTP() = default;
//  virtual void foo() override { }  // CRTP<T> is abstract.
};

struct Derived1 : CRTP<Derived1> {
    Derived1 (const Base& base) : Base(base) { }
    Derived1() = default;
    virtual void foo() override { }
};

struct Derived2 : CRTP<Derived1> {
    Derived2 (const Base& base) : Base(base) { }
    Derived2() = default;
    virtual void foo() override { }
};

template <typename T, typename U>
T* convert (const U& u) {
//  return new T(u);  // This works, but only if T(const Base&) constructor is defined in every Base concrete derived type.
    return dynamic_cast<T*>(new CRTP<T>(u));  // This only works if CRTP<T> is not abstract.
}

int main() {
    Derived1 d1;
    Derived2* d = convert<Derived2, Derived1>(d1);
}
C++ Templates 复制构造函数

评论

3赞 πάντα ῥεῖ 5/3/2022
尽管存在一些非常特殊的情况,但将静态多态性与动态多态性混为一谈没有多大意义。您能详细说明一下您想用它解决的实际用例吗?对我来说看起来像一个 xy 问题。
2赞 Pete Becker 5/3/2022
关于术语的次要观点:不是复制构造函数。复制构造函数采用正在构造的类型的参数:、 或 。T(const Base&)T(T&)T(const T&)T(volatile T&)T(const volatile T&)
1赞 Eljay 5/3/2022
对于多态的“复制构造函数”(并且是一个很好的现代C++公民),通常的习惯习惯是有一个,这样派生的类就可以通过 来复制自己的副本,并且可能在这个过程中使用它们自己的实际复制构造函数。virtual std::unique_ptr<Base> clone() const;auto p = q->clone();

答:

0赞 kasos5000 5/4/2022 #1

但是,事实上,它不是一个复制构造函数,所以它可以简单地像这样委托:

struct Derived1 : CRTP<Derived1> {
    using CRTP<Derived1>::CRTP;
    Derived1() = default;
    virtual void foo() override {
    }
};

您也可以使用指针而不是引用,顺便说一下,这似乎与您的代码更相关,因为 convert() 返回一个指针。此类构造函数不被视为复制构造函数,并且始终可以委托给子级。