MST

星途 面试题库

面试题:C++ 中赋值运算符与拷贝构造函数的差异基础考查

请详细阐述 C++ 中赋值运算符(operator=)和拷贝构造函数在定义形式、调用时机上的主要差异,并举例说明。
36.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

定义形式差异

  1. 赋值运算符(operator=
    • 是一个成员函数,其定义形式为类名& operator=(const 类名& other)。例如:
class MyClass {
public:
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {
            // 执行赋值操作,如释放原有资源,分配新资源并复制数据
            //...
        }
        return *this;
    }
};
  1. 拷贝构造函数
    • 也是一个成员函数,定义形式为类名(const 类名& other)。例如:
class MyClass {
public:
    MyClass(const MyClass& other) {
        // 执行深拷贝操作,如分配新资源并复制数据
        //...
    }
};

调用时机差异

  1. 赋值运算符(operator=
    • 当一个已存在的对象被赋予另一个同类型对象的值时调用。例如:
MyClass obj1;
MyClass obj2;
obj1 = obj2; // 调用赋值运算符
  1. 拷贝构造函数
    • 当用一个已存在的对象创建新对象时调用,包括函数传参(传值方式)和函数返回(返回值方式)。例如:
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赋值。