【发布时间】:2017-11-14 00:36:52
【问题描述】:
我有以下类定义:
class A {...}
class B : public class A {...}
和一个所有者类定义:
class C {
A* a;
public:
C (A* a) { this->a = a; }
}
然后当我尝试调用以下内容时,一切都很好:
B* b = new B();
C(b);
但是我有以下所有者类定义:
class C {
std::unique_ptr<A> a;
public:
C(std::unique_ptr<A>& a) { this->a = std::move(a); }
}
当我尝试调用以下命令时,我收到一个编译器错误,提示无法从 B 的 unique_ptr 转换为 A 的 unique_ptr&:
std::unique_ptr<B> b(new B());
C(b);
我确实意识到 std::unique_ptr& 和 std::unique_ptr 是不一样的。但我不确定将唯一指针传递给所属类的标准协议是什么。
我尝试了以下方法:
class C {
std::unique_ptr<A> a;
public:
C(std::unique_ptr<A> a) { this->a = std::move(a); }
}
和
std::unique_ptr<B> b = std::make_unique<B>();
C(std::move(b));
这可行,但感觉反直觉,因为使用 unique_ptr 而不是 shared_ptr 的部分目的是通过不必复制内存地址来提高性能。但在这种情况下,它不是复制内存地址,而是创建一个全新的 unique_ptr 以仅按值传递它,只是在函数超出范围后将其丢弃。
注意:我使用的是 VS C++11 编译器
【问题讨论】:
-
给func函数一个unique_ptr:func(a.get());
-
根据文档 (en.cppreference.com/w/cpp/memory/unique_ptr/make_unique)
std::make_unique是 C++ 14(因此 您已经在使用 C++ 14 功能)。否则,我认为std::unique_ptr在 C++ 11 和 14 之间没有任何重大变化。您的C构造函数可能应该是:C(std::unique_ptr<A>&& a) : a(std::move(a)) {}。 -
@sailfish009 类 C 需要获得指针的所有权,所以你的答案是行不通的。
-
@jahithber 如果你通过了 func(a.release()) 那么你的类可以取得对象的所有权。
-
@Abhishek 好的,我明白了。我看到这一点的方式是,当您通过指向函数的指针传递时,不期望所有权将被转移。因此调用者代码可能会在指针上调用 delete 并导致问题。具有唯一指针作为其输入参数的函数明确表示它将对指针的唯一性做一些事情,因此存在转移所有权的期望。所以也许函数可以这样写: public: C(A*& a) { m_a = a; a = nullptr; }
标签: c++11 unique-ptr