删除构造函数的Foo类结合RVO与unique_ptr的代码运行疑问
问题分析与解答
代码示例
class Foo { public: Foo(const Foo&) = delete; Foo& operator=(const Foo&) = delete; Foo() = delete; }; std::unique_ptr<Foo> CreateFoo() { return std::unique_ptr<Foo>(); } int main(int argc, char** argv) { std::unique_ptr<Foo> result = CreateFoo(); return 0; }
问题描述
由于拷贝构造函数和赋值运算符被删除,Foo类不可移动构造,同时我也删除了默认构造函数。但这段代码能正常运行,且result is nullptr。我知道RVO适用时无需拷贝/移动构造函数,但我还删除了默认构造函数,这是怎么回事?
解答
核心原因是你根本没有创建任何Foo类的实例。
std::unique_ptr<Foo>()创建的是一个空的智能指针,它内部并没有指向任何Foo对象——既不会调用Foo的默认构造函数,也不需要用到Foo的拷贝/移动构造逻辑。
你可能混淆了智能指针本身的构造和它所指向对象的构造:
std::unique_ptr本身的默认构造函数是允许的,它会把指针成员初始化为nullptr,和Foo类的构造函数完全无关。- 只有当你用
std::make_unique<Foo>()或者显式调用new Foo()时,才会尝试创建Foo的实例,这时候才会触发Foo的构造函数检查。
你的代码里,CreateFoo()返回的是空智能指针,main里的result也只是接收这个空指针,全程没有触及Foo类的任何构造逻辑,所以编译器不会报错,最终result自然是nullptr。
内容的提问来源于stack exchange,提问作者Bruce
相关产品推荐
相关产品推荐

