#include <iostream>
struct person_t{
int age;
};
person_t get_person1(){
person_t person;
person.age = 10;
return person;
}
person_t * get_person2(){
person_t *person = new person_t;
person->age = 20;
return person;
}
int main(){
person_t person1 = get_person1();
person_t *person2 = get_person2();
std::cout << person1.age << std::endl;
std::cout << person2->age << std::endl;
delete person2;
return 0;
}
我想知道从函数返回结构的最安全的方法是什么。
正如在here和here中对问题的回答一样,据说当你在get_person1()
中创建一个对象时,该对象会在它熄灭后被销毁范围。
但是当我搜索“如何从函数c ++返回结构”时,它建议我使用方法一(使用get_person1()
)(示例here)。但我认为该方法会在调用函数后销毁对象,我认为方法2是最安全的。
我在这里错了..?或者关于这个话题的任何意见..?
谢谢!
答案 0 :(得分:8)
使用按值返回有三个原因:
答案 1 :(得分:4)
据说当你在
get_person1()
中创建一个对象时,该对象将在超出范围后被销毁。
销毁的是本地对象(即person
内的get_persion1()
)。返回的是该对象的副本:复制struct person_t
(也可以移动它)。所以,这是安全的。
get_person2()
也是安全的,但请考虑使用智能指针而不是原始指针:
std::unique_ptr<person_t> get_person2(){
auto person = std::make_unique<person_t>();
// For pre-C++14
// std::unique_ptr<person_t> person(new person_t);
person->age = 20;
return person;
}
这样,get_person2()
的来电者不必致电delete
(可能会忘记这样做)。
答案 2 :(得分:4)
两种方法都同样安全 - 两者都不会导致未定义的行为,并且函数内部设置的值会使其返回给调用者。
主要区别在于第一种方法复制struct
,而第二种方法复制指向struct
的指针。当struct
很小时,例如在您的示例中,没有区别。当struct
变大时,返回指针可能会以额外的内存分配为代价来节省一些CPU周期,因此远远不能保证获胜。
显然,第二种方法有另一个缺点,即最终必须delete
struct
。第一种方法不受此要求的限制。
答案 3 :(得分:2)
这两种方法都是安全的。
方法1是安全的,因为从函数范围复制了本地person
。通常,Return Value Optimization (RVO)可用于避免复制。
方法2也是安全的,因为person
实例的内存是在堆中分配的。这种分配显然在函数范围之外有效。但是,您必须记住在完成使用后释放所述内存。这在您的示例代码中并不重要。 Heap-allocations are automatically deallocated when main terminates,所以对于您的简短示例,您实际上“不需要”delete person2
。
您的问题是哪种方法“最安全”。虽然我认为绝大多数C ++程序员会建议方法2支持方法1,但这是不可能客观回答的。许多C ++程序员会建议使用智能指针。
最后评论:方法1和方法2根本不同。在堆栈上分配内存(方法1)与在堆上分配内存(方法2)是两个不同的概念。 There are many more considerations to make but "safety" considerations