c++ - 可以在基类中定义复制构造函数并仍然处理派生类情况吗?

标签 c++ copy virtual c++03

我的类结构如下:

class P {
    public:
        virtual std::auto_ptr<P> clone() const=0;
};

class A : public P {
    public:
        std::auto_ptr<P> clone() const {
            return std::auto_ptr<P>(new A(*this));
        }
};

class B : public P {
    public:
        std::auto_ptr<P> clone() const {
            return std::auto_ptr<P>(new B(*this));
        }
};

class C : public P {
    public:
        std::auto_ptr<P> clone() const {
            return std::auto_ptr<P>(new C(*this));
        }
};

这只是复制构造函数的代码:类 ABC 在其他方面都有不同的代码。这里有很多代码重复,能不能简化一下?

最佳答案

使用 CRTP,您可以:

template <typename Derived, typename Base>
struct Clonable : public Base
{
    std::auto_ptr<Base> clone() const {
        return std::auto_ptr<Base>(new Derived(static_cast<const Derived&>(*this)));
    }
};

class A : public Clonable<A, P> {}; 
class B : public Clonable<B, P> {}; 
class C : public Clonable<C, P> {}; 

为了使派生类的实型受益,我会将代码修改为:

class P {
public:
    std::auto_ptr<P> clone() const { return std::auto_ptr<P>(vclone()); }
private:
    virtual P* vclone() const = 0;
};

template <typename Derived, typename Base>
struct Clonable : public Base
{
    std::unique_ptr<Derived> clone() const {
        return std::unique_ptr<Derived>(static_cast<Derived*>(vclone()));
    }
private:
    // Cannot use covariant-type `Derived*` in CRTP as Derived is not complete yet
    Base* vclone() const {
        return new Derived(static_cast<const Derived&>(*this));
    }
};

class A : public Clonable<A, P> {}; 
class B : public Clonable<B, P> {}; 
class C : public Clonable<C, P> {}; 

因此,以下是有效的:

A a;
std::auto_ptr<A> a_copy =  a.clone();

关于c++ - 可以在基类中定义复制构造函数并仍然处理派生类情况吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59414984/

相关文章:

winforms - WinForm文本框: MenuStrip keyboard shortcuts overriding OS-level copy/paste

c++ - c++中虚继承是什么

c++ - 'this'指针是否参与虚函数多态行为

c++ - 转换为联编文件

c++ - 创建静态哨兵节点的正确方法是什么

javascript - 跨浏览器 JS/jQuery 将当前 URL 复制到剪贴板

emacs - 使用 ido.el 在 emacs 上使用 dired 复制粘贴各种文件

c++ - C++ 中的协变返回类型到底是什么?

c++ - lambda 采用 `char` 参数

c++ - 为什么这些创建字符串的方法之间有如此大的差异