C ++中std :: shared_ptr的克隆模式 [英] Clone pattern for std::shared_ptr in C++

查看:542
本文介绍了C ++中std :: shared_ptr的克隆模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么要(为了使其编译)中间的CloneImplementationstd::static_pointer_cast(请参见下面的 3 部分)对std::shared_ptr使用克隆模式,而不是使用更接近的内容(请参阅下面的 2 节)以使用原始指针(请参阅下面的 1 节)?因为据我了解,std::shared_ptr具有广义复制构造函数和广义赋值运算符?

Why do you need (in order to make it compile) the intermediate CloneImplementation and std::static_pointer_cast (see Section 3 below) to use the Clone pattern for std::shared_ptr instead of something closer (see Section 2 below) to the use of raw pointers (see Section 1 below)? Because as far as I understand, std::shared_ptr has a generalized copy constructor and a generalized assignment operator?

1.带有原始指针的克隆模式:

#include <iostream>

struct Base {
    virtual Base *Clone() const {
        std::cout << "Base::Clone\n";
        return new Base(*this);
    }
};

struct Derived : public Base {
    virtual Derived *Clone() const override {
        std::cout << "Derived::Clone\n";
        return new Derived(*this);
    }
};

int main() {
  Base *b = new Derived;
  b->Clone();
}

2.具有共享指针的克隆模式(天真尝试):

#include <iostream>
#include <memory>

struct Base {
    virtual std::shared_ptr< Base > Clone() const {
        std::cout << "Base::Clone\n";
        return std::shared_ptr< Base >(new Base(*this));
    }
};
struct Derived : public Base {
    virtual std::shared_ptr< Derived > Clone() const override {
        std::cout << "Derived::Clone\n";
        return std::shared_ptr< Derived >(new Derived(*this));
    }
};

int main() {
  Base *b = new Derived;
  b->Clone();
}

输出:

error: invalid covariant return type for 'virtual std::shared_ptr<Derived> Derived::Clone() const'
error:   overriding 'virtual std::shared_ptr<Base> Base::Clone() const'

3.具有共享指针的克隆模式:

#include <iostream>
#include <memory>

struct Base {

    std::shared_ptr< Base > Clone() const {
        std::cout << "Base::Clone\n";
        return CloneImplementation();
    }

private:

    virtual std::shared_ptr< Base > CloneImplementation() const {
        std::cout << "Base::CloneImplementation\n";
        return std::shared_ptr< Base >(new Base(*this));
    }
};
struct Derived : public Base {

    std::shared_ptr< Derived > Clone() const {
        std::cout << "Derived::Clone\n";
        return std::static_pointer_cast< Derived >(CloneImplementation());
    }

private:

    virtual std::shared_ptr< Base > CloneImplementation() const override {
        std::cout << "Derived::CloneImplementation\n";
        return std::shared_ptr< Derived >(new Derived(*this));
    }
};

int main() {
  Base *b = new Derived;
  b->Clone();
}

推荐答案

C ++中的一般规则是,覆盖函数必须具有与其覆盖的函数相同的签名.唯一的区别是指针和引用允许协方差:如果继承的函数返回A*A&,则只要A是的基类,则重写器可以分别返回B*B&. B.这条规则使 1 节可以正常工作.

The general rule in C++ is that the overriding function must have the same signature as the function it overrides. The only difference is that covariance is allowed on pointers and references: if the inherited function returns A* or A&, the overrider can return B* or B& respectively, as long as A is a base class of B. This rule is what allows Section 1 to work.

另一方面,std::shared_ptr<Derived>std::shared_ptr<Base>是两个完全不同的类型,它们之间没有继承关系.因此,不可能从替代程序返回一个而不是另一个. 2 在概念上与尝试用std::string f() override覆盖virtual int f()相同.

On the other hand, std::shared_ptr<Derived> and std::shared_ptr<Base> are two totally distinct types with no inheritance relationship between them. It's therefore not possible to return one instead of the other from an overrider. Section 2 is conceptually the same as trying to override virtual int f() with std::string f() override.

这就是为什么需要 some 额外的机制来使智能指针表现出协变行为的原因.您在 3 部分中显示的就是这样一种可能的机制.它是最通用的一种,但在某些情况下,也存在替代方法.例如:

That's why some extra mechanism is needed to make smart pointers behave covariantly. What you've shown as Section 3 is one such possible mechanism. It's the most general one, but in some cases, alternatives also exist. For example this:

struct Base {
    std::shared_ptr< Base > Clone() const {
        std::cout << "Base::Clone\n";
        return std::shared_ptr< Base >(CloneImplementation());
    }

private:
    virtual Base* CloneImplementation() const {
        return new Base(*this);
    }
};

struct Derived : public Base {
     std::shared_ptr< Derived > Clone() const {
        std::cout << "Derived::Clone\n";
        return std::shared_ptr< Derived >(CloneImplementation());
    }

private:
    virtual Derived* CloneImplementation() const override {
        std::cout << "Derived::CloneImplementation\n";
        return new Derived(*this);
    }
};

这篇关于C ++中std :: shared_ptr的克隆模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆