面试题答案
一键面试-
设计思路:
- 拷贝构造函数和赋值运算符重载:为
MyClass
定义拷贝构造函数和赋值运算符重载,确保在拷贝对象时,数据能够正确复制,不会出现浅拷贝等问题,保证数据完整性。 - 移动构造函数和移动赋值运算符重载:定义移动构造函数和移动赋值运算符重载,提高在移动对象时的效率,同时保证数据的正确转移,避免资源泄漏等问题。
- 异常安全:在所有可能抛出异常的操作中,确保对象处于一个合理的状态,不会导致数据不一致。比如在构造函数中,如果部分资源分配成功但后续操作抛出异常,要正确释放已分配的资源。
- 使用
std::enable_if
和类型 traits:在模板函数或成员函数中,可以使用std::enable_if
和类型 traits 来检查类型是否满足特定条件,增强类型安全。例如,确保MyClass
满足可拷贝、可移动等条件才能被list
存储。
- 拷贝构造函数和赋值运算符重载:为
-
代码片段:
#include <iostream>
#include <list>
#include <type_traits>
class MyClass {
private:
int data;
public:
// 构造函数
MyClass(int value) : data(value) {}
// 拷贝构造函数
MyClass(const MyClass& other) : data(other.data) {
std::cout << "Copy constructor called" << std::endl;
}
// 赋值运算符重载
MyClass& operator=(const MyClass& other) {
if (this != &other) {
data = other.data;
std::cout << "Assignment operator called" << std::endl;
}
return *this;
}
// 移动构造函数
MyClass(MyClass&& other) noexcept : data(other.data) {
other.data = 0;
std::cout << "Move constructor called" << std::endl;
}
// 移动赋值运算符重载
MyClass& operator=(MyClass&& other) noexcept {
if (this != &other) {
data = other.data;
other.data = 0;
std::cout << "Move assignment operator called" << std::endl;
}
return *this;
}
~MyClass() {
std::cout << "Destructor called" << std::endl;
}
int getData() const {
return data;
}
};
template<typename T>
typename std::enable_if<std::is_copy_constructible<T>::value && std::is_move_constructible<T>::value, void>::type
testList() {
std::list<MyClass> myList;
MyClass obj1(10);
myList.push_back(obj1);
MyClass obj2(20);
myList.push_back(std::move(obj2));
for (const auto& obj : myList) {
std::cout << "Data in list: " << obj.getData() << std::endl;
}
}
int main() {
testList<MyClass>();
return 0;
}
在上述代码中:
MyClass
类定义了拷贝构造函数、赋值运算符重载、移动构造函数和移动赋值运算符重载,确保在不同操作下数据的完整性和一致性。testList
函数使用了std::enable_if
和类型 traits 来确保MyClass
满足可拷贝和可移动的条件,才进行list
的相关操作,增强了类型安全。在main
函数中调用testList
函数来演示MyClass
对象在list
中的存储和操作。