MST
星途 面试题库

面试题:C++ 类缺省函数默认行为的深层次探究与场景分析

在C++ 11引入移动语义后,类的缺省函数行为有了新的变化。对于一个拥有动态资源的类`class DynamicResource { std::unique_ptr<int[]> data; int length; public: // 未定义任何缺省函数 };`,请详细阐述编译器生成的默认移动构造函数和默认移动赋值运算符重载函数的行为,以及它们与默认拷贝构造函数和默认赋值运算符重载函数在不同应用场景下的选择依据,比如性能敏感场景和资源管理场景等。
33.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

默认移动构造函数行为

  1. 资源转移:编译器生成的默认移动构造函数会将源对象的data指针直接转移到新创建的对象中,同时将源对象的length赋值给新对象。之后,源对象的data会被置为nullptr,这样源对象就不再拥有动态资源,避免了资源的重复释放。
  2. 浅拷贝性质:本质上,这是一种浅拷贝,但由于std::unique_ptr的特性,实现了资源的有效转移。例如:
DynamicResource source;
source.data = std::make_unique<int[]>(5);
source.length = 5;
DynamicResource destination(std::move(source));
// 此时source.data为nullptr,destination.data指向原来source.data指向的内存

默认移动赋值运算符重载函数行为

  1. 资源释放与转移:首先,目标对象会释放自身已有的动态资源(如果有)。然后,将源对象的data指针和length值转移过来,并将源对象的data置为nullptr。例如:
DynamicResource source, destination;
source.data = std::make_unique<int[]>(3);
source.length = 3;
destination = std::move(source);
// 此时destination.data指向原来source.data指向的内存,source.data为nullptr

与默认拷贝构造函数和默认赋值运算符重载函数选择依据

  1. 性能敏感场景
    • 移动语义优势:在性能敏感场景下,移动语义更具优势。移动构造和移动赋值操作只是转移资源的控制权,而不是进行数据的逐元素拷贝。例如在函数返回对象时,如果使用拷贝构造函数,会对整个对象的数据进行拷贝,开销较大;而使用移动构造函数,只是转移资源指针,性能大幅提升。
    • 拷贝语义劣势:拷贝构造函数和赋值运算符重载函数会进行深拷贝,对于大对象或包含大量动态资源的对象,深拷贝的时间和空间开销都很大。
  2. 资源管理场景
    • 移动语义:移动语义能确保资源的正确转移和唯一所有权。当需要将一个对象的资源“移动”到另一个对象时,移动语义能避免资源的重复释放和内存泄漏。例如在容器操作中,将对象从一个容器移动到另一个容器,移动语义能高效地管理资源。
    • 拷贝语义:拷贝语义适用于需要保留源对象状态,同时创建一个完全独立副本的场景。比如在某些需要对数据进行备份或者需要独立操作副本的情况下,拷贝构造函数和赋值运算符重载函数更合适。