唯一指针创建对象的副本,但我想避免复制

Unique Pointer Creating copy of the object but i want to avoid the copy

我在某处读到,如果你想通过引用 return 一个局部变量通过智能指针来做,这段代码背后的动机与我想 return a Test class 变量而没有创建副本,或者换句话说 Return a local variable with reference 。但是每次 return 语句执行时它都会调用析构函数。谁能帮助我通过智能指针实现我的目标。这是我的示例代码。

#include <iostream>
#include <memory>
#include <unistd.h>


class Test {
public:
    Test() {
        std::cout << "I am the constructor of A \n";
    }

    ~Test() {
        std::cout << "I am the Distructor of A \n";
    }

};


std::unique_ptr<Test> num() {
    Test obj;
    std::unique_ptr<Test> newInt = std::make_unique<Test>(obj);
    return newInt;
};


int main() {
    std::unique_ptr<Test> ptr = num();
    sleep(12);
}
1> std::unique_ptr<Test> num() {
2>     Test obj;
3>     std::unique_ptr<Test> newInt = std::make_unique<Test>(obj);
4>     return newInt;
5> };

在第 3 行中,它创建了一个新的 Test 对象并将 obj 复制分配给新对象。 析构函数实际上是为 obj 变量调用的。

在您提供的示例中,我认为不需要 obj,只需一个 Test 对象即可。

std::unique_ptr<Test> num() {
    std::unique_ptr<Test> newInt = std::make_unique<Test>();
    /* do something with newInt */
    return newInt;
};

输出:

Program returned: 0
Program stdout
I am the constructor of A 
I am the Distructor of A 

当函数 num 超出范围时调用 Test 的析构函数,因为在堆栈上有一个名为 obj 的本地 Test 实例,即,具有自动处理的生命周期。这是您的 return 值指向对象在您调用

时从中复制初始化的对象
std::unique_ptr<Test> newInt = std::make_unique<Test>(obj);
//                                              ^^^^^^^^^^
//                                              results in copy ctor called
return newInt;

您可以通过将函数定义为

来避免这种情况
std::unique_ptr<Test> num() {
    std::unique_ptr<Test> newInt = std::make_unique<Test>();
    return newInt;
};

除此之外,您的推理有些误入歧途。根据保证的复制省略,您可以 return 一个对象的值而不复制它。在您的情况下,启用 C++17 后,您还可以

Test num() {
    return Test{};
};

Test t = num();

即使您明确删除了 Test 的复制构造函数:

Test(const Test&) = delete;

您正在 num 函数中创建本地对象,这当然会导致 obj 的破坏。在您的情况下,它会导致两种不同的破坏。第二个发生在主函数退出并且 uniqie_ptr 的析构函数启动之后。像这样尝试:

#include <iostream>
#include <memory>
#include <unistd.h>


class Test {
public:
    Test() {
        std::cout << "I am the constructor of A \n";
    }

    ~Test() {
        std::cout << "I am the destructor of A \n";
    }

};


std::unique_ptr<Test> num() {
    std::unique_ptr<Test> obj = std::make_unique<Test>();

    // stuff with obj

    return obj;
};


int main() {
    std::unique_ptr<Test> ptr = num();
    sleep(12);
    return 0;
}