[C++高频精进] 面向对象编程:类与对象

核心要点速览

  • 访问控制:public(接口)、private(实现)、protected(继承)
  • const 成员:const 成员变量需初始化列表初始化;const 成员函数不可修改成员变量
  • static 成员:静态成员变量类共享、类外初始化;静态成员函数无 this 指针、仅访问静态成员
  • 构造函数:可重载、非虚函数;含默认 / 带参 / 拷贝 / 移动构造
  • 析构函数:不可重载;基类需设为虚函数避免资源泄漏
  • 类大小:仅取决于非静态数据成员,遵循内存对齐

一、基本概念

  • 类:抽象的数据类型模板,定义对象的属性(数据成员)和行为(成员函数)。
  • 对象:类的具体实例,占用实际内存,拥有类定义的属性和行为。

二、核心特性:封装

核心是 “隐藏实现细节,暴露公共接口”,通过访问控制符实现。

访问控制符可访问范围作用
public类内、类外、派生类暴露接口,供外部调用
private仅类内和友元隐藏数据成员和内部实现
protected类内、友元、派生类(类外不可访问)为继承预留访问权限
  • 封装意义:保障数据安全、提升代码维护性、降低使用复杂度。

三、构造函数:对象的初始化

  • 核心特点:函数名与类名相同,无返回值,对象创建时自动调用,可重载,不能为虚函数。

常见类型

1. 默认构造函数
  • 定义:无参数,或所有参数都有默认值。
  • 编译器行为:未定义任何构造函数时自动生成;定义其他构造函数后需手动定义。
2. 带参构造函数
  • 用途:通过参数灵活初始化对象。
3. 拷贝构造函数
  • 定义:参数必须为 “同类对象的 const 引用”(避免无限递归)。
  • 调用时机:对象初始化、函数按值传参、函数返回值为对象(非引用)。
  • 浅拷贝 vs 深拷贝:
    • 浅拷贝:仅复制表层数据,指针成员共享内存,可能导致双重释放。
    • 深拷贝:为指针成员重新分配内存并复制数据,示例:
    class String {
    private:
        char* str;
    public:
        String(const String& other) {
            str = new char[strlen(other.str) + 1];
            strcpy(str, other.str);
        }
        ~String() { delete[] str; }
    };
4. 移动构造函数
  • 核心:接管原对象动态资源,避免拷贝,提升效率。
  • 示例:
    class String {
    private:
        char* str;
    public:
        String(String&& other) noexcept {
            str = other.str;
            other.str = nullptr; // 掏空原对象
        }
    };
    String s2 = std::move(s1); // 接管s1资源

初始化列表

  • 用途:优先初始化成员变量,推荐使用。
  • 必须使用的场景:const 成员、引用成员、无默认构造函数的类成员,示例:
    class A {
    private:
        const int a;
        int& b;
    public:
        A(int x, int& y) : a(x), b(y) {} // 初始化列表
    };

四、析构函数:对象的清理

  • 特点:函数名~类名,无参数、无返回值,不可重载,对象生命周期结束时自动调用。
  • 必须手动定义的场景:类包含动态分配资源(如 new 的内存)。
  • 虚析构函数(基类必备,避免资源泄漏):
    class Base {
    public:
        virtual ~Base() { delete[] data; } // 虚析构
    };
    class Derived : public Base {
    public:
        ~Derived() { delete[] derivedData; }
    };

五、this 指针

  • 本质:非静态成员函数中隐式传递的指针,指向当前调用对象(类型类名* const)。
  • 用途:
    void setName(string name) { this->name = name; } // 区分成员与参数
    Person& setAge(int age) { return *this; } // 链式调用

六、静态成员(属于类)

1. 静态成员变量

  • 特点:所有对象共享,存储在全局数据区,类内声明、类外初始化:
    class Counter {
    public:
        static int count; // 类内声明
    };
    int Counter::count = 0; // 类外初始化

2. 静态成员函数

  • 特点:无 this 指针,无需创建对象即可调用,仅能访问静态成员:
    static void increment() { count++; } // 仅访问静态成员
    Counter::increment(); // 直接调用

七、类的大小计算

  • 规则:仅取决于非静态数据成员,遵循内存对齐,与成员函数、静态成员无关。
  • 示例:
    class Empty {};
    sizeof(Empty); // 1字节(占位)
    class A { char c; int i; };
    sizeof(A); // 8字节(1+3填充+4,对齐系数4)

八、问答

  • 构造函数和析构函数的调用顺序?
    • 构造:先定义先构造;析构:后构造先析构。
  • 拷贝构造函数的参数为什么必须是引用?
    • 避免值传递引发的无限递归(形参初始化需再次调用拷贝构造)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值