将std::unique_ptr类成员标记为const
Marking std::unique_ptr class member as const
很多使用std::unique_ptr
管理类依赖关系所有权的例子如下:
class Parent
{
public:
Parent(Child&& child) :
_child(std::make_unique<Child>(std::move(child))){}
private:
std::unique_ptr<Child> _child;
};
我的问题是标记_child
成员为const
是否有任何意想不到的副作用?(除了确保reset()
, release()
等不能在_child
上调用)。
我问,因为我还没有在一个例子中看到它,不知道这是故意的还是只是为了简洁/一般
由于std::unique_ptr
(对象的唯一所有权)的性质,它需要没有任何复制构造函数。move构造函数(6)只接受非const右值引用,这意味着如果你试图让你的_child
const
并移动它,你会得到一个很好的编译错误:)
即使自定义unique_ptr
将接受const右值引用,也不可能实现。
缺点与任何const
成员一样:赋值和移动赋值操作符不能正常工作(它们需要您覆盖_child
),并且从父类移动不会窃取_child
(性能错误)。这样的代码也不常见,可能会让人感到困惑。
增益是边际的,因为_child
是private
,因此只能从Parent
内部访问,因此围绕更改_child
而破坏不变量的代码量仅限于需要维护不变量的成员函数和友元。
我无法想象这样做的好处会大于坏处,但是如果你这样做了,你当然可以按照自己的方式去做,而不会破坏程序的其他部分。
是的,你可以这样做,这是我在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
}
这与在c++ 03代码中编写Ui::MyWidget *const ui
完全相同。
上面的代码创建了一个新对象,但是没有理由不使用问题中的std::move()
传递一个对象。
相关文章:
- 将 AlphaMode 成员设置为 DXGI_SWAP_CHAIN_DESC1 会使 CreateSwapChainFo
- 默认移动成员定义为已删除,而未定义特殊成员?
- 将常量引用成员设置为临时变量是否安全
- 对象超出范围后,引用成员设置为 0
- 为什么当类的数据成员更改为引用时输出不同
- 给定仅包含布尔类型成员的结构的两个对象 s1 和 s2,只要 s1 的成员为 true,请检查 s2 的每个成员是否为真
- 为什么一个非平凡的成员需要为同一类中的匿名联合定义构造函数
- 将CPP类成员设置为SQLite DB中的列
- 将范围从成员更改为全局功能
- 将静态常量成员替换为静态成员函数的优点
- 将非零矢量成员读取为阵列和输出点产品
- 将数组的成员设置为零
- 如何将成员声明为指向外部"C"函数的指针?
- const成员返回为非const
- C++:如何将数据成员定义为 const
- C++:将模板参数的模板类型成员加为好友的语法正确吗
- 为什么没有将虚拟静态成员添加为C++的一个功能
- 为什么constexpr静态成员(类型为class)需要定义
- 将类成员存储为RapidXML数据类型
- 成员对象为unique_ptr或在堆栈上