面试题答案
一键面试拷贝构造函数实现深拷贝
假设 ComplexObject
类定义如下:
#include <iostream>
#include <cstring>
class NestedClass {
public:
int data;
NestedClass(int val) : data(val) {}
};
class OtherObject {};
class ComplexObject {
private:
int* dynamicArray;
int arraySize;
OtherObject* otherObjectPtr;
NestedClass nestedObj;
public:
ComplexObject(int size) : arraySize(size), nestedObj(0) {
dynamicArray = new int[arraySize];
for (int i = 0; i < arraySize; ++i) {
dynamicArray[i] = i;
}
otherObjectPtr = new OtherObject();
}
// 拷贝构造函数
ComplexObject(const ComplexObject& other) : arraySize(other.arraySize), nestedObj(other.nestedObj.data) {
dynamicArray = new int[arraySize];
std::memcpy(dynamicArray, other.dynamicArray, arraySize * sizeof(int));
otherObjectPtr = new OtherObject(*other.otherObjectPtr);
}
~ComplexObject() {
delete[] dynamicArray;
delete otherObjectPtr;
}
};
性能优化讨论
- 避免不必要的拷贝:如果有可能,尽量使用移动语义。在C++11 引入了移动构造函数和移动赋值运算符,通过转移资源所有权而不是拷贝资源来提高性能。例如,可以定义移动构造函数如下:
ComplexObject(ComplexObject&& other) noexcept
: dynamicArray(other.dynamicArray), arraySize(other.arraySize),
otherObjectPtr(other.otherObjectPtr), nestedObj(std::move(other.nestedObj)) {
other.dynamicArray = nullptr;
other.otherObjectPtr = nullptr;
other.arraySize = 0;
}
- 减少内存分配次数:如果动态数组的大小已知且相对固定,可以考虑使用对象池来预先分配内存,减少每次创建对象时的内存分配开销。
- 优化内存拷贝操作:对于较大的动态数组,可以考虑使用更高效的内存拷贝算法,例如
std::memcpy
的某些优化版本,在某些平台上可能比标准库版本更快。 - 使用智能指针:使用
std::unique_ptr
或std::shared_ptr
来管理动态分配的资源,这样可以避免手动管理内存,减少内存泄漏风险,并且在某些情况下可以通过智能指针的优化机制提高性能。例如,可以将OtherObject* otherObjectPtr
改为std::unique_ptr<OtherObject> otherObjectPtr
。