簡體   English   中英

將引用參數傳遞給采用 unique_ptr 的通用引用的函數

[英]passing reference argument to function taking universal reference of unique_ptr

我有兩個無法更改其簽名的函數。 第一個引用一個對象,而第二個引用一個指向同一對象的唯一指針的通用引用。 我不確定如何將第一個參數傳遞給第二個參數。

我已經嘗試通過使用引用的地址傳遞一個新的唯一 ptr,但是由於引用是抽象的,編譯器會抱怨未實現的方法。

下面是一個例子:

// Example program
#include <iostream>
#include <memory>


class MyAbstractClass {
public:
  virtual void doSomething() = 0;    
};

class MyConcreteClass : public MyAbstractClass {
public:
  void doSomething() override {
    std::cout << "Hello I do something" << std::endl;
  }
};

class MyUserClass {
public:
  MyUserClass(MyAbstractClass& mac){
    // the line below doesn't work !!
    doSomethingElse(std::make_unique<MyAbstractClass>(&mac));
  }
  void doSomethingElse(std::unique_ptr<MyAbstractClass>&& mac){
    mac->doSomething();
  }  
};


int main() {
  MyConcreteClass mcc;
  MyUserClass muc(mcc);
}

您的編譯器會抱怨,因為make_unique在您嘗試實例化的類型上調用了new ,從而有效地復制了現有對象。 當然,它不能這樣做,因為該類是抽象的。

除非你有辦法保證傳遞給MyUserClass的引用是一個動態(“堆”)變量(並且它的指針不被擁有等),你不能只在unique_ptr捕獲它的指針,然后在doSomethingElse之后釋放它。 即使這是有保證的,就您所知, doSomethingElse仍然可以嘗試刪除指針本身(除非您確切地知道它的作用)。 當您通過右值引用傳遞它時,對象在doSomethingElse返回后可能不再有效。

這意味着您必須制作對象的副本。 但是,您無法制作普通副本。 您需要復制整個、非抽象的底層對象。

如果您被允許更改類的簽名,那么添加一個虛擬clone方法就可以了。

如果沒有,一個不是絕對可怕的解決方法可能是(你需要事先知道所有繼承MyAbstractClass的類型) switch(typeid(mac))dynamic_cast

暫無
暫無

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

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