C++拷贝构造函数介绍

2024-01-02 14:17:42

介绍

C++拷贝构造函数是一个特殊的成员函数,它用于创建类对象的一个副本(即深复制)。当一个新对象被创建并且其初始值来自同类的另一个对象时,拷贝构造函数会被自动调用。以下是拷贝构造函数的主要特点:

  1. 定义
    拷贝构造函数具有单个参数,该参数是对本类类型的引用,并且通常为const引用,以防止意外修改原对象。

    class MyClass {
    public:
        // 拷贝构造函数声明
        MyClass(const MyClass& other); // 或者 MyClass(MyClass const &other);
    
        // ...其他成员变量和成员函数...
    };
    
  2. 调用时机

    • 当一个新对象通过现有对象进行初始化时。
    • 当一个对象作为函数的参数以值传递时。
    • 当一个对象从函数返回时(如果返回类型是对象而不是引用或指针)。
    • 在某些STL容器(如vector、list等)中插入元素时。
  3. 行为
    拷贝构造函数负责正确地初始化新对象,这可能包括:

    • 复制所有数据成员的值。
    • 如果类包含指针或其他资源(例如文件句柄、网络连接等),则需要分配新的资源并复制这些资源的内容,而非简单地复制指针。
    • 调用基类的拷贝构造函数来复制基类部分的状态。
  4. 默认行为与自定义

    • 如果程序员没有显式提供拷贝构造函数,编译器将生成一个默认的拷贝构造函数,它会逐个成员地执行浅复制(对于指针,只复制指针本身而不复制指针指向的数据)。
    • 对于包含动态内存分配、共享资源或其他需要特殊处理的情况,通常需要自定义拷贝构造函数来确保正确地管理资源。
  5. 常量引用参数
    参数通常使用const引用的原因是避免不必要的临时对象创建和销毁,同时表明不会更改传入的对象状态。虽然不强制要求const,但在实际编程实践中几乎总是选择const引用,以遵循最佳实践。

应用举例

#include <iostream>
#include <cstring> // 用于memcpy

class String {
public:
    // 普通构造函数,初始化字符串
    String(const char* str) : length(strlen(str)), content(new char[length + 1]) {
        memcpy(content, str, length + 1); // 包括结束符'\0'
    }

    // 拷贝构造函数(深度拷贝)
    String(const String& other) : length(other.length), content(new char[other.length + 1]) {
        memcpy(content, other.content, length + 1);
    }

    // 析构函数,释放内存资源
    ~String() {
        delete[] content;
    }

    // 省略了赋值运算符重载以简化示例,实际项目中也需要进行深拷贝

private:
    int length;
    char* content;
};

int main() {
    String s1("Hello, World!");
    String s2(s1); // 这里会调用拷贝构造函数进行深度拷贝

    std::cout << s1.content << std::endl; // 输出 "Hello, World!"
    std::cout << s2.content << std::endl; // 输出 "Hello, World!"

    return 0;
}
实例说明

在上述例子中,String 类有一个指向动态分配的字符数组的指针成员 content。默认的浅拷贝行为只会复制这个指针,而不是复制指针所指向的数据。因此,在使用默认的浅拷贝构造函数时,当源对象和副本对象都析构时,它们会试图删除同一块内存区域,导致未定义的行为。通过自定义拷贝构造函数,我们为 s2 分配新的内存,并将 s1 的内容复制到新内存中,这样 s1s2 就各自拥有独立的字符串数据,实现了深度拷贝。

总结

在实现拷贝构造函数时,一定要注意是否存在指针,或者其它资源(不能通过简单赋值完成的),就需要对指针所指的空间进行数据复制,不能只是简单的复制指针复制的浅复制。

文章来源:https://blog.csdn.net/scy518/article/details/135333569
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。