簡體   English   中英

包含唯一指針成員變量的類的 C++ 賦值運算符

[英]C++ Assignment operator for class that contains a unique pointer member variable

我知道如果我有一個帶有智能唯一指針的類,則無法將該類分配給另一個實例,因為無法復制唯一指針。 我知道我可以使唯一指針成為共享指針,這將解決問題。 但是如果我不想共享指針的所有權怎么辦? 是否可以創建一個賦值運算符來移動唯一指針並復制其他變量?

我讀過你可以使用std::move來傳遞所有權。

#include <iostream>
#include <memory> 

struct GraphStructure { };

class test {

        int a;
        std::vector<int> vector;
        std::unique_ptr<GraphStructure> Graph_; 
 };

 int main () {

     test t1;
     auto t2 = t1;
 }

由於成員( graph_ )不可復制,類test的默認復制構造函數被刪除(如果您仍然可以以任何有意義的方式復制,例如通過創建圖形成員的深層副本,您必須自己實現復制構造函數)。 相比之下,默認的移動構造函數仍然存在( std::unique_ptr是可移動的)。 所以你可以做的是:

test t1;
auto t2 = std::move(t1);

但是請注意, t1將不再持有任何對象(您移動了該對象,因此您將其內容移動到另一個)並且先前由t2持有的對象將被銷毀。 如果這是一個有意義的狀態由您決定......

旁注:我寫的關於復制和移動構造函數的內容也適用於復制和移動賦值......

用簡單的方法解決這個問題

如果GraphStructure是一個沒有任何虛成員函數的類或結構,這很容易做到。 我們可以編寫一個函數來復制unique_ptr的數據以創建一個新的GraphStructure

std::unique_ptr<GraphStructure> duplicate(std::unique_ptr<GraphStructure> const& ptr)
{
    return std::make_unique<GraphStructure>(*ptr);
}

一旦我們有了duplicate ,我們就可以使用這個類來編寫一個用於測試的復制構造函數:

class test {
    std::unique_ptr<GraphStructure> ptr;
    std::vector<int> values;
   public:
    // this can be defaulted
    test() = default;
    // we use duplicate to create a copy constructor
    test(const test& source) 
      : ptr(duplicate(source.ptr)))
      , values(source.values)
    {}
    // we can use the default move constructor
    test(test&&) = default;

    test& operator=(test const& source) {
        ptr = duplicate(source.ptr);
        values = source.values; 
        return *this;
    }
    // we can use the default move assignment operator 
    test& operator=(test&&) = default;
};

如果 GraphStructure 有虛方法怎么辦?

在這種情況下,向 GraphStructure 添加一個虛擬clone方法,該方法返回一個新的std::unique_ptr<GraphStructure>

class GraphStructure {
   public:
    // override this method in child classes
    virtual std::unique_ptr<GraphStructure> clone() {
        return std::make_unique<GraphStructure>(*this);
    }
    virtual ~GraphStructure() {}
};

然后,使用.clone()代替duplicate

暫無
暫無

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

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