簡體   English   中英

將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是否有任何意想不到的副作用? (除了確保無法在_child上調用reset()release()等)。

我問,因為我還沒有在一個例子中看到它,不知道這是故意還是僅僅是為了簡潔/普遍。

由於std::unique_ptr (對象的唯一所有權)的性質,因此無需任何復制構造函數。 移動構造函數 (6)只接受非const rvalue-references,這意味着如果你試圖使你的_child const移動它,你會得到一個很好的編譯錯誤:)

即使自定義unique_ptr采用const rvalue-reference,也無法實現。

缺點就像任何const成員一樣:賦值和移動賦值運算符不能正常工作(它們需要你覆蓋_child ),而且從父級移動不會竊取_child (性能錯誤)。 編寫這樣的代碼也很常見,可能會讓人感到困惑。

增益是微不足道的,因為_childprivate ,因此只能從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()傳遞一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM