Returning a shared_ptr

Returning a shared_ptr

本文关键字:ptr shared Returning      更新时间:2023-10-16

我有一个函数需要返回另一个类的新对象,所以我认为我需要将其返回对象保存在共享指针中。喜欢这个

在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);
}