我想知道的是,如何按值返回 a Cat
实际上不同于返回 std::unique_ptr<Cat>
在传递它们、内存管理和在实践中使用它们方面。
内存管理方面,它们不一样吗?由于按值返回的对象和包装在 unique_ptr 中的对象一旦超出范围就会触发它们的析构函数?
那么,您将如何比较这两段代码:
Cat catFactory(string catName) {
return Cat(catName);
}
std::unique_ptr<Cat> catFactory(string catName) {
return std::unique_ptr(new Cat(catName));
}
最佳答案
按值返回应被视为默认值。 (*) 偏离默认做法,返回 std::unique_ptr<Cat>
, 应该需要理由。
返回指针的主要原因有以下三个:
多态性。这是返回的最佳理由
std::unique_ptr<Cat>
而不是Cat
: 您实际上可能正在创建一个派生自Cat
的类型的对象.如果你需要这种多态性,你绝对需要返回某种指针。这就是工厂函数通常返回指针的原因。Cat
无法廉价移动或根本无法移动。 “本质上”不可移动的类型很少见;你通常应该尝试修复Cat
通过使其廉价移动。但当然Cat
可能是其他人拥有的类型,您不能向其添加移动构造函数(甚至可能是复制构造函数)。在这种情况下,除了使用unique_ptr
之外,您无能为力。 (并向所有者投诉)。该函数有可能失败并且无法构造任何有效的
Cat
.在这种情况下,一种可能性是按值返回,但如果Cat
则抛出异常。无法 build ;另一个,在 C++11/C++14 中,是让函数返回std::unique_ptr<Cat>
。并让它在没有Cat
时返回空指针可以构造。但是,在 C++17 中,您应该开始返回std::optional<Cat>
而不是std::unique_ptr<Cat>
在这种情况下,避免不必要的堆分配。
(*) 当被调用的函数需要它自己的值拷贝时,这也适用于传递 对象,例如, 将初始化类成员的构造函数它的论据之一。按值接受对象并移动。
关于c++ - 我什么时候应该按值返回,而不是返回一个唯一的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44447292/