gpt4 book ai didi

c++11 - C++中std::shared_ptr的克隆模式

转载 作者:行者123 更新时间:2023-12-03 16:15:09 30 4
gpt4 key购买 nike

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

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&,则重写器可以分别返回B*B&,只要AB的基类。该规则使Section 1 可以正常工作。

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

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

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++11 - C++中std::shared_ptr的克隆模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43586090/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com