面试题答案
一键面试定义形式差异
- 赋值运算符(
operator=
):- 是一个成员函数,其定义形式为类名& operator=(const 类名& other)。例如:
class MyClass {
public:
MyClass& operator=(const MyClass& other) {
if (this != &other) {
// 执行赋值操作,如释放原有资源,分配新资源并复制数据
//...
}
return *this;
}
};
- 拷贝构造函数:
- 也是一个成员函数,定义形式为类名(const 类名& other)。例如:
class MyClass {
public:
MyClass(const MyClass& other) {
// 执行深拷贝操作,如分配新资源并复制数据
//...
}
};
调用时机差异
- 赋值运算符(
operator=
):- 当一个已存在的对象被赋予另一个同类型对象的值时调用。例如:
MyClass obj1;
MyClass obj2;
obj1 = obj2; // 调用赋值运算符
- 拷贝构造函数:
- 当用一个已存在的对象创建新对象时调用,包括函数传参(传值方式)和函数返回(返回值方式)。例如:
MyClass obj1;
MyClass obj2(obj1); // 调用拷贝构造函数
void func(MyClass obj) { // 传值方式调用函数,参数传递时调用拷贝构造函数
//...
}
MyClass func2() {
MyClass temp;
return temp; // 返回值方式调用,返回时调用拷贝构造函数(优化后可能省略)
}
举例说明
#include <iostream>
#include <cstring>
class String {
private:
char* str;
int length;
public:
String(const char* s = nullptr) {
if (s == nullptr) {
length = 0;
str = new char[1];
str[0] = '\0';
} else {
length = strlen(s);
str = new char[length + 1];
strcpy(str, s);
}
}
// 拷贝构造函数
String(const String& other) {
length = other.length;
str = new char[length + 1];
strcpy(str, other.str);
}
// 赋值运算符
String& operator=(const String& other) {
if (this != &other) {
delete[] str;
length = other.length;
str = new char[length + 1];
strcpy(str, other.str);
}
return *this;
}
~String() {
delete[] str;
}
void print() {
std::cout << str << std::endl;
}
};
int main() {
String s1("Hello");
String s2(s1); // 调用拷贝构造函数
s2.print();
String s3;
s3 = s1; // 调用赋值运算符
s3.print();
return 0;
}
在上述代码中,s2(s1)
调用拷贝构造函数创建新对象s2
,而s3 = s1
调用赋值运算符给已存在的对象s3
赋值。