[英]Marking std::unique_ptr class member as const
A lot of the examples for using std::unique_ptr
to manage ownership of class dependencies look like the following: 使用
std::unique_ptr
管理类依赖项所有权的许多示例如下所示:
class Parent
{
public:
Parent(Child&& child) :
_child(std::make_unique<Child>(std::move(child))){}
private:
std::unique_ptr<Child> _child;
};
My question is whether marking the _child
member as const
have any unexpected side effects? 我的问题是将
_child
成员标记为const
是否有任何意想不到的副作用? (Aside from being ensuring that reset()
, release()
etc. cannot be called on _child
). (除了确保无法在
_child
上调用reset()
, release()
等)。
I ask since I have not yet seen it in an example and don't whether that is intentional or just for brevity/generality. 我问,因为我还没有在一个例子中看到它,不知道这是故意还是仅仅是为了简洁/普遍。
Because of the nature of a std::unique_ptr
(sole ownership of an object) it's required to have no copy constructor whatsoever. 由于
std::unique_ptr
(对象的唯一所有权)的性质,因此无需任何复制构造函数。 The move constructor (6) only takes non-const rvalue-references which means that if you'd try to make your _child
const
and move it you'd get a nice compilation error :) 移动构造函数 (6)只接受非const rvalue-references,这意味着如果你试图使你的
_child
const
移动它,你会得到一个很好的编译错误:)
Even if a custom unique_ptr
would take a const rvalue-reference it would be impossible to implement. 即使自定义
unique_ptr
采用const rvalue-reference,也无法实现。
The downsides are like with any const
member: That the assignment and move-assignment operators don't work right (they would require you to overwrite _child
) and that moving from the parent would not steal the _child
(performance bug). 缺点就像任何
const
成员一样:赋值和移动赋值运算符不能正常工作(它们需要你覆盖_child
),而且从父级移动不会窃取_child
(性能错误)。 Also it is uncommon to write code like this, possibly confusing people. 编写这样的代码也很常见,可能会让人感到困惑。
The gain is marginal because _child
is private
and therefore can only be accessed from inside the Parent
, so the amount of code that can break invariants revolving around changing _child
is limited to member functions and friends which need to be able to maintain invariants anyways. 增益是微不足道的,因为
_child
是private
,因此只能从Parent
内部访问,因此可以打破围绕更改_child
不变量的代码量仅限于需要能够维护不变量的成员函数和朋友。
I cannot imagine a situation where the gain would outweigh the downsides, but if you do you can certainly do it your way without breakage of other parts of the program. 我无法想象收益会超过下行的情况,但如果你这样做,你当然可以按照自己的方式去做,而不会破坏程序的其他部分。
Yes, you can do this, and it's what I regularly do when implementing UI classes in Qt: 是的,你可以这样做,这是我在Qt中实现UI类时经常做的事情:
namespace Ui {
class MyWidget
}
class MyWidget : public QWidget
{
Q_OBJECT
const std::unique_ptr<Ui::MyWidget> ui;
public:
explicit MyWidgetQWidget *parent = 0)
: ui(new Ui::MyWidget{})
{
}
~MyWidgetQWidget();
// destructor defined as = default in implementation file,
// where Ui::MyWidget is complete
}
It's exactly comparable to writing Ui::MyWidget *const ui
in C++03 code. 它与在C ++ 03代码中编写
Ui::MyWidget *const ui
完全相同。
The above code creates a new object, but there's no reason not to pass one in using std::move()
as in the question. 上面的代码创建了一个新对象,但没有理由不在问题中使用
std::move()
传递一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.