唯一指针创建对象的副本,但我想避免复制
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;
}
我在某处读到,如果你想通过引用 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;
}