C++三大默认成员函数详解

C++ 类的默认成员函数

在 C++ 中,类有六个特殊的默认成员函数。其中构造函数析构函数拷贝构造函数是最基础且最常用的三个。若未显式定义,编译器会自动生成默认版本,但特定场景需手动实现以正确管理资源。


1. 构造函数 (Constructor)
  • 作用:在对象创建时初始化成员变量,分配资源。
  • 特点

    • 函数名与类名相同,无返回值。
    • 可重载(多个不同参数的构造函数)。
    • 默认构造函数无参数;若未定义任何构造函数,编译器自动生成空实现的默认构造函数。
  • 示例

    class MyClass {
    public:
        int a;
        double b;
        // 默认构造函数
        MyClass() : a(0), b(0.0) {}
        // 带参构造函数
        MyClass(int x, double y) : a(x), b(y) {}
    };
    // 使用
    MyClass obj1;         // 调用默认构造函数
    MyClass obj2(10, 3.14); // 调用带参构造函数
    

2. 析构函数 (Destructor)
  • 作用:在对象销毁时释放资源(如堆内存、文件句柄)。
  • 特点

    • 函数名为 ~类名,无参数和返回值。
    • 每个类仅有一个析构函数,不可重载。
    • 若未显式定义,编译器生成空实现的默认析构函数(可能引发资源泄漏)。
  • 示例

    class ResourceHolder {
    public:
        int* data;
        // 构造函数中分配资源
        ResourceHolder(int size) {
            data = new int[size];
        }
        // 析构函数中释放资源
        ~ResourceHolder() {
            delete[] data; // 避免内存泄漏
        }
    };
    // 使用
    {
        ResourceHolder obj(100); // 构造函数调用
    } // 离开作用域时,析构函数自动调用
    

    http://my.tv.sohu.com/us/443606061/713394435.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDQzNS5zaHRtbA==.html
    http://my.tv.sohu.com/us/443606061/713394520.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDUyMC5zaHRtbA==.html
    http://my.tv.sohu.com/us/443606061/713394280.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDI4MC5zaHRtbA==.html
    http://my.tv.sohu.com/us/443606061/713394281.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDI4MS5zaHRtbA==.html
    http://my.tv.sohu.com/us/443606061/713394282.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDI4Mi5zaHRtbA==.html
    http://my.tv.sohu.com/us/443606061/713394368.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDM2OC5zaHRtbA==.html
    http://my.tv.sohu.com/us/443606061/713394452.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDQ1Mi5zaHRtbA==.html
    http://my.tv.sohu.com/us/443606061/713394373.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDM3My5zaHRtbA==.html
    http://my.tv.sohu.com/us/443606061/713394300.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDMwMC5zaHRtbA==.html
    http://my.tv.sohu.com/us/443606061/713394388.shtml
    https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDM4OC5zaHRtbA==.html


3. 拷贝构造函数 (Copy Constructor)
  • 作用:用同类型对象初始化新对象(深拷贝场景必需)。
  • 特点

    • 函数签名:类名(const 类名& other)
    • 调用场景:对象初始化(如 MyClass obj2 = obj1;)、传参、返回值。
    • 默认拷贝构造函数执行浅拷贝(直接复制指针地址),深拷贝需手动实现。
  • 示例

    class StringContainer {
    public:
        char* str;
        // 构造函数
        StringContainer(const char* s) {
            str = new char[strlen(s) + 1];
            strcpy(str, s);
        }
        // 拷贝构造函数(深拷贝)
        StringContainer(const StringContainer& other) {
            str = new char[strlen(other.str) + 1];
            strcpy(str, other.str);
        }
        ~StringContainer() {
            delete[] str;
        }
    };
    // 使用
    StringContainer s1("Hello");
    StringContainer s2 = s1; // 调用拷贝构造函数
    

关键注意事项

  1. 资源管理

    • 若类涉及动态内存或外部资源,必须手动实现析构函数和拷贝构造函数(或禁用拷贝)。
    • 默认浅拷贝会导致重复释放内存(双重释放错误)。
  2. 编译器默认行为

    • 未定义时,编译器生成默认版本:
      • 构造函数:无操作。
      • 析构函数:无操作。
      • 拷贝构造函数:逐成员浅拷贝。
  3. 现代 C++ 改进

    • 使用 = default 显式要求编译器生成默认函数:
      MyClass() = default; // 显式生成默认构造函数
      
    • 使用 = delete 禁用函数:
      MyClass(const MyClass&) = delete; // 禁用拷贝
      

      http://my.tv.sohu.com/us/443606061/713394435.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDQzNS5zaHRtbA==.html
      http://my.tv.sohu.com/us/443606061/713394520.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDUyMC5zaHRtbA==.html
      http://my.tv.sohu.com/us/443606061/713394280.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDI4MC5zaHRtbA==.html
      http://my.tv.sohu.com/us/443606061/713394281.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDI4MS5zaHRtbA==.html
      http://my.tv.sohu.com/us/443606061/713394282.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDI4Mi5zaHRtbA==.html
      http://my.tv.sohu.com/us/443606061/713394368.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDM2OC5zaHRtbA==.html
      http://my.tv.sohu.com/us/443606061/713394452.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDQ1Mi5zaHRtbA==.html
      http://my.tv.sohu.com/us/443606061/713394373.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDM3My5zaHRtbA==.html
      http://my.tv.sohu.com/us/443606061/713394300.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDMwMC5zaHRtbA==.html
      http://my.tv.sohu.com/us/443606061/713394388.shtml
      https://tv.sohu.com/v/dXMvNDQzNjA2MDYxLzcxMzM5NDM4OC5zaHRtbA==.html

掌握这三个函数是理解 C++ 对象生命周期和资源管理的基础,尤其在涉及动态内存时需谨慎设计。

© 版权声明

相关文章