C++类和对象(中篇):深入理解默认成员函数

C++面向对象真没那么难:类与对象(上篇)-优快云博客文章浏览阅读571次,点赞9次,收藏10次。刚学C++的来看!!!!面向对象真没那么难 https://blog.youkuaiyun.com/wz_290793/article/details/149486147?spm=1001.2014.3001.5502C++类和对象(下):从初始化列表到编译器优化-优快云博客刚学c++的来看!!! https://blog.youkuaiyun.com/wz_290793/article/details/149523760?spm=1001.2014.3001.5502

目录

C++类和对象(中篇):深入理解默认成员函数

一、默认成员函数:类自带的“出厂配置”

二、构造函数:对象的“出生证明”

2.1 构造函数的作用

2.2 构造函数的秘密

三、析构函数:对象的“临终遗言”

3.1 何时需要析构

3.2 析构函数的特点

四、拷贝构造:对象的“克隆技术”

4.1 深浅拷贝之争

4.2 拷贝构造规则

五、赋值重载:对象的“身份复制”

5.1 运算符重载基础

5.2 赋值运算符重载

5.3 赋值 vs 拷贝构造

六、实战:日期类综合实现

下篇预告:面向对象终极奥义


C++类和对象(中篇):深入理解默认成员函数

​类就像一辆新车,默认成员函数是它的“出厂设置”​
掌握构造、析构和拷贝构造,让你的对象从“能用”变成“好用”!

一、默认成员函数:类自带的“出厂配置”

每个类都有6个​​自动生成​​的默认成员函数(前4个最重要):

class YourClass {
    // 编译器自动生成以下6个函数:
    YourClass();             // 1. 构造函数
    ~YourClass();            // 2. 析构函数
    YourClass(const YourClass&); // 3. 拷贝构造
    YourClass& operator=(const YourClass&); // 4. 赋值重载
    // ...(后两个取地址重载较少用)
};

​核心原则​​:

  1. 不写时,编译器自动生成
  2. 自动生成的版本是否满足需求?
  3. 不满足时,如何自己实现?

二、构造函数:对象的“出生证明”

2.1 构造函数的作用

替代C语言中的Init()函数,​​自动完成初始化​​:

class Date {
public:
    // 构造函数(类名相同)
    Date(int year = 1, int month = 1, int day = 1) {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};

// 创建对象自动调用构造
Date today(2024, 7, 21); // 带参构造
Date defaultDay;        // 默认构造(无参)

2.2 构造函数的秘密

  1. ​必须与类同名​
  2. ​没有返回值​​(连void都不写)
  3. ​对象创建时自动调用​
  4. ​可以重载​​(不同参数版本)
  5. ​默认构造三选一​​:
    • 无参构造 Date()
    • 全缺省构造 Date(int y=1, int m=1, int d=1)
    • 编译器自动生成的构造

⚠️ ​​易错点​​:Date d3(); 会被当成函数声明!


三、析构函数:对象的“临终遗言”

3.1 何时需要析构

当类管理​​资源​​(内存、文件句柄等)时必须手动实现:

class Stack {
public:
    Stack(int n = 4) {
        _a = (int*)malloc(sizeof(int) * n); // 申请资源
    }
    
    ~Stack() {  // 析构函数(~类名)
        free(_a);     // 释放资源
        _a = nullptr;
        cout << "资源已释放!" << endl;
    }
private:
    int* _a;
    int _capacity;
    int _top;
};

3.2 析构函数的特点

  1. 名称是 ​~类名
  2. ​无参数无返回值​
  3. ​对象销毁时自动调用​
  4. ​多个对象按创建顺序反向析构​​(后进先出)

💡 像Date这样没有资源的类,不需要写析构!


四、拷贝构造:对象的“克隆技术”

4.1 深浅拷贝之争

​浅拷贝​​:只复制指针地址(危险!)
​深拷贝​​:复制指针指向的内容(安全)

// 正确实现深拷贝
Stack(const Stack& st) {
    _a = (int*)malloc(sizeof(int) * st._capacity);
    memcpy(_a, st._a, sizeof(int) * st._top);
    _top = st._top;
    _capacity = st._capacity;
}

4.2 拷贝构造规则

  1. ​必须是引用传参​​:Date(const Date& d)
  2. ​参数通常加const保护​
  3. ​自定义类型传值会触发拷贝构造​

✨ 何时需要深拷贝?类中有​​指针指向动态资源​​时!


五、赋值重载:对象的“身份复制”

5.1 运算符重载基础

让自定义类型支持 +, -, == 等操作:

class Date {
public:
    // 重载==运算符
    bool operator==(const Date& d) const {
        return _year == d._year 
            && _month == d._month 
            && _day == d._day;
    }
};

5.2 赋值运算符重载

Date& operator=(const Date& d) {
    if(this != &d) { // 防止自我赋值
        _year = d._year;
        _month = d._month;
        _day = d._day;
    }
    return *this; // 支持连续赋值 d1 = d2 = d3;
}

5.3 赋值 vs 拷贝构造

​场景​使用拷贝构造使用赋值重载
​对象创建时​Date d2 = d1;❌ 不适用
​对象已存在​❌ 不适用d2 = d1;

六、实战:日期类综合实现

class Date {
public:
    // 构造
    Date(int y = 1900, int m = 1, int d = 1);
    
    // 析构(无资源,不需要实现)
    
    // 拷贝构造
    Date(const Date& d) : _year(d._year), _month(d._month), _day(d._day) {}
    
    // 赋值重载
    Date& operator=(const Date& d) {
        if(this != &d) {
            _year = d._year;
            _month = d._month;
            _day = d._day;
        }
        return *this;
    }
    
    // 比较运算符
    bool operator<(const Date& d) const { /* 实现 */ }
    bool operator==(const Date& d) const { /* 实现 */ }
    
    // 日期计算
    Date operator+(int days) const;
    Date& operator+=(int days);
    
private:
    int _year;
    int _month;
    int _day;
};

未完持续...(关注我,宝子,C++学习带你飞起来!!!)

现在只需掌握:​​构造负责出生,析构负责善后,拷贝实现克隆​
动手实现一个Student类(包含姓名/学号/拷贝构造),遇到问题随时回看~🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值