簡體   English   中英

返回shared_ptr

[英]Returning a shared_ptr

我有一個需要返回另一個類的新對象的函數,所以我想我需要將其返回對象保存在共享指針中。 像這樣

X班

Y* func(param)
{
   return new Y(param);
}

我嘗試將其更改為

std::shared_ptr<Y> func(param)
{
   std::shared_ptr<Y> y(new Y(param));
   return y;
}

我不想返回本地對象,那么該怎么辦?

我建議您將std::shared_ptr作為返回類型,並return std::make_shared<Y>()以轉讓所有權。

這是一個可能會幫助您的工作示例:

#include <memory>
#include <iostream>
#include <string>

class Y {
public:
    Y(const std::string& n)
    : name{n} {}

    std::string name;
};

std::shared_ptr<Y> func()
{
    return std::make_shared<Y>("new class");
}

int main()
{
    std::shared_ptr<Y> p_class = func();
    std::cout << p_class->name;
    // outputs: "new class"

    return 0;
}

您返回一個堆分配的對象,這意味着您轉移所有權。 我建議您使用std::unique_ptr作為返回類型

std::unique_ptr<Y> func(param)
{
   return std::unique_ptr<Y>(new Y(param));
}

更好的方法是使用std :: make_unique(如果已經可用,否則編寫您自己的)或-如果您使用shared_ptr-std :: make_shared。 對於異常安全性和在shared_ptr效率更高的情況下,這樣做更好。

std::unique_ptr<Y> func(param)
{
   return make_unique<Y>(param);
}

std::shared_ptr<Y> func(param)
{
   return std::shared_ptr<Y>(param);
}

並且請注意,您的func復制了參數。 您可能需要使用轉發來避免這種情況。

template<class T, class U>
std::unique_ptr<T> make_unique1(U&& u)
{
    return std::unique_ptr<T>(new T(std::forward<U>(u)));
}

template<class T, class... U>
std::unique_ptr<T> make_unique(U&&... u)
{
    return std::unique_ptr<T>(new T(std::forward<U>(u)...));
}

除了我的建議std::unique_ptr答案外,我想指出的是,不必在堆上創建對象以從函數返回它。 您可以按值返回新對象:

Y func(param)
{
   Y result(param);
   return result;
}

如果Y是可復制的,這將(並且一直有效)起作用。 如果該類不可復制,它將無法工作;如果有效,則可能涉及復制對象。

盡管大多數編譯器多年來都沒有刪除該副本,但是如果您返回未命名的臨時對象,則標准C++17現在必須這樣做。 這意味着即使您有不可復制且不可移動的對象,以下代碼也將編譯並返回一個新對象:

class Y {
  public:
  Y(int i): value(i) {}
  Y(Y const&) = delete;
  Y(Y&&) = delete;
  Y& operator=(Y const&) = delete;
  Y& operator=(Y&&) = delete;

  int value;
};

Y foo(int i) {
  return Y(i);
}

void bar {
  Y y = foo(42);
}

暫無
暫無

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

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