当我运行此代码时:
#include <memory>
#include <iostream>
class A {
public:
virtual std::unique_ptr<A> clone() = 0;
};
class B : public A {
private:
int b0;
public:
B(const B& b) { b0 = b.get_b0(); }
B(const int& b0) : b0(b0) {}
std:: unique_ptr<A> clone() { return std::make_unique<B>(*this); }
const int& get_b0() const { return b0; }
int& get_b0() { return b0; }
};
class box {
private:
std::unique_ptr<A> o;
public:
box(const box& sp) { o = sp.o->clone(); }
box(std::unique_ptr<A> o) : o(std::move(o)) {}
std::unique_ptr<A> get_o() { return o->clone(); }
};
void foo(std::unique_ptr<box> sp) {
std::unique_ptr<A> o = sp->get_o();
if(const B *ptr1 = dynamic_cast<const B*>(o.get()))
std::cout << ptr1->get_b0() << std::endl;
if(const B *ptr = dynamic_cast<const B*>(sp->get_o().get()))
std::cout << ptr->get_b0() << std::endl;
}
int main() {
B b(100);
box sp(std::make_unique<B>(b));
foo(std::make_unique<box>(sp));
return 0;
}
输出为:
100
3579964222 (some random integer!!!)
如果我放弃
std::unique_ptr
,并将其替换为 std::shared_ptr
,代码就会开始工作。但在我的用例中,shared_ptr
可能会导致问题,因为更改一个对象可能会影响其他对象。clone()
的方式是否是良好的代码实践?
这是未定义的行为,
ptr
是一个悬空指针。
表达式
sp->get_o()
生成 std::unique_ptr<A>
的 临时对象。