C++系列(十):面向对象编程终极指南!从封装到多态,彻底掌握类与对象的核心奥秘

引言

面向对象编程(OOP)是现代软件开发的核心范式,C++通过封装继承多态三大特性提供了强大的面向对象能力。这些特性使代码更易维护、扩展和复用,是构建复杂系统的基石。本章将深入探讨C++类和对象的方方面面,从基础封装到高级多态应用,帮助您掌握面向对象编程的精髓。

最后,如果大家喜欢我的创作风格,请大家多多关注up主,你们的支持就是我创作最大的动力!如果各位观众老爷觉得我哪些地方需要改进,请一定在评论区告诉我,马上改!在此感谢大家了。

各位观众老爷,本文通俗易懂,快速熟悉C++,收藏本文,关注up不迷路,后续将持续分享C++纯干货(请观众老爷放心,绝对又干又通俗易懂)。请多多关注、收藏、评论,评论区等你~~~



文章目录

  • 引言
  • 一、封装:数据与行为的结合
    • 1.1 封装的基本概念
    • 1.2 类定义与对象创建
    • 1.3 访问权限控制
    • 1.4 成员属性私有化实践
  • 二、对象初始化和清理
    • 2.1 构造函数与析构函数
    • 2.2 深拷贝与浅拷贝
    • 2.3 初始化列表
  • 三、面向对象高级特性
    • 3.1 静态成员
    • 3.2 友元机制
  • 四、运算符重载
    • 4.1 基本运算符重载
    • 4.2 特殊运算符重载
  • 五、继承与多态
    • 5.1 继承基础
    • 5.2 多态实现
    • 5.3 虚析构函数
  • 六、高级面向对象技巧
    • 6.1 抽象类与接口
    • 6.2 多重继承与虚继承
  • 七、实战案例:电脑组装系统



正 文

一、封装:数据与行为的结合

1.1 封装的基本概念

封装是OOP的第一特性,它将数据(属性)和操作数据的方法(行为)捆绑为一个整体(类),并控制对内部数据的访问权限。

核心优势

  • 数据保护:防止外部直接访问内部数据
  • 接口抽象:提供清晰的对外接口
  • 实现隐藏:隐藏内部实现细节

1.2 类定义与对象创建

// 学生类定义
class Student {
public:
    // 设置姓名
    void setName(string name) {
        m_name = name;
    }
    
    // 显示学生信息
    void showInfo() {
        cout << "姓名:" << m_name << ",学号:" << m_id << endl;
    }

private:
    string m_name;  // 姓名
    int m_id;       // 学号
};

int main() {
    // 创建学生对象
    Student stu;
    stu.setName("张三");
    stu.showInfo();
    
    return 0;
}

1.3 访问权限控制

C++提供三种访问权限:

权限 类内访问 类外访问 子类访问
public
protected
private

示例:银行账户封装

class BankAccount {
public:
    void deposit(double amount) {
        if (amount > 0) balance += amount;
    }
    
    double getBalance() const {
        return balance;
    }

private:
    double balance = 0.0;  // 余额对外不可见
};

1.4 成员属性私有化实践

优点

  1. 精确控制读写权限
  2. 数据有效性验证
  3. 内部实现可灵活变更
class Temperature {
public:
    void setCelsius(double c) {
        if (c < -273.15) {
            cout << "温度不能低于绝对零度!" << endl;
            return;
        }
        celsius = c;
    }
    
    double getFahrenheit() const {
        return celsius * 9/5 + 32;
    }

private:
    double celsius;  // 摄氏温度
};

二、对象初始化和清理

2.1 构造函数与析构函数

对象生命周期管理的关键方法:

方法 调用时机 特点
构造函数 对象创建时 可重载,可带参数
析构函数 对象销毁时 无参数,不可重载

示例:资源管理

class FileHandler {
public:
    // 构造函数打开文件
    FileHandler(string filename) {
        file.open(filename);
        cout << "打开文件: " << filename << endl;
    }
    
    // 析构函数关闭文件
    ~FileHandler() {
        if (file.is_open()) {
            file.close();
            cout << "关闭文件" << endl;
        }
    }

private:
    fstream file;
};

2.2 深拷贝与浅拷贝

关键区别

  • 浅拷贝:简单值复制(默认行为)
  • 深拷贝:复制指针指向的内容

深拷贝实现

class StringWrapper {
public:
    // 构造函数
    StringWrapper(const char* str) {
        size = strlen(str);
        data = new char[size + 1];
        strcpy(data, str);
    }
    
    // 深拷贝构造函数
    StringWrapper(const StringWrapper& other) {
        size = other.size;
        data = new char[size + 1];
        strcpy(data, other.data);
    }
    
    // 析构函数
    ~StringWrapper() {
        delete[] data;
    }

private:
    char* data;
    size_t size;
};

2.3 初始化列表

高效初始化成员变量的方法:

class Vector3D {
public:
    // 使用初始化列表
    Vector3D(float x, float y, float z) 
        : x(x), y(y), z(z) {}
    
    // 传统初始化方式(效率较低)
    Vector3D(float a, float b, float c) {
        x = a;
        y = b;
        z = c;
    }

private:
    float x, y, z;
};

三、面向对象高级特性

3.1 静态成员

静态成员属于类而非对象:

静态成员变量

class Employee {
public:
    static int count;  // 员工计数
    
    Employee() {
        count++;
    }
    
    ~Employee() {
        count--;
    }
};

// 类外初始化
int Employee::count = 0;

静态成员函数

class MathUtils {
public:
    static double pi() {
        return 3.1415926535;
    }
    
    static int add(int a, int b) {
        return a + b;
    }
};

// 使用
double circleArea = MathUtils::pi() * radius * radius;

3.2 友元机制

突破封装限制的特殊访问权限:

友元函数

class SecureContainer {
    friend void debugAccess(SecureContainer& obj);
private:
    string secret = "Top Secret";
};

void debugAccess(SecureContainer& obj) {
    cout << "访问机密数据: " << obj.secret << endl;
}

友元类

class Sensor {
    friend class MonitoringSystem;
private:
    float internalTemp;
};

class MonitoringSystem {
public:
    void readSensor(Sensor& s) {
        cout << "传感器温度: " << s.internalTemp << endl;
    }
};

四、运算符重载

4.1 基本运算符重载

class Complex {
public:
    Complex(double r, double i) : real(r), imag(i) {}
    
    // 加法运算符重载
    Complex operator+(const Complex& other) {
        return Complex(real + other.real, imag + other.imag);
    }
    
    // 输出运算符重载(友元函数)
    friend ostream& operator<<(ostream& os, const Complex& c);

private:
    double real, imag;
};

ostream& operator<<(ostream& os, const Complex& c) {
    os << c.real << " + " << c.imag << "i";
    return os;
}

4.2 特殊运算符重载

赋值运算符

class DynamicArray {
public:
    // 赋值运算符重载
    DynamicArray& operator=(const DynamicArray& other) {
        if (this != &other) {
            delete[] data;
            size = other.size;
            data = new int[size];
            copy(other.data, other.data + size, data);
        }
        return *this;
    }

private:
    int* data;
    size_t size;
};

函数调用运算符(仿函数)

class RandomGenerator {
public:
    int operator()(int min, int max) {
        static random_device rd;
        static mt19937 gen(rd());
        uniform_int_distribution<> dis(min, max);
        return dis(gen);
    }
};

// 使用
RandomGenerator rand;
int dice = rand(1, 6);

五、继承与多态

5.1 继承基础

// 基类:形状
class Shape {
public:
    virtual double area() const = 0;  // 纯虚函数
    virtual void draw() const {
        cout << "绘制形状" << endl;
    }
};

// 派生类:圆形
class Circle : public Shape {
public:
    Circle(double r) : radius(r) {}
    
    double area() const override {
        return 3.14159 * radius * radius;
    }
    
    void draw() const override {
        cout << "绘制圆形,半径: " << radius << endl;
    }

private:
    double radius;
};

5.2 多态实现

运行时多态三要素

  1. 继承关系
  2. 虚函数重写(override)
  3. 基类指针/引用指向派生类对象

示例

void renderShape(const Shape& shape) {
    shape.draw();
    cout << "面积: " << shape.area() << endl;
}

int main() {
    Circle circle(5.0);
    renderShape(circle);  // 多态调用
    
    return 0;
}

5.3 虚析构函数

解决基类指针删除派生类对象时的资源释放问题:

class Base {
public:
    virtual ~Base() {
        cout << "Base 析构" << endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        data = new int[100];
    }
    
    ~Derived() override {
        delete[] data;
        cout << "Derived 析构" << endl;
    }

private:
    int* data;
};

int main() {
    Base* obj = new Derived();
    delete obj;  // 正确调用Derived的析构函数
    return 0;
}

六、高级面向对象技巧

6.1 抽象类与接口

// 抽象数据库接口
class Database {
public:
    virtual void connect() = 0;
    virtual void query(const string& sql) = 0;
    virtual ~Database() = default;
};

// MySQL实现
class MySQLDatabase : public Database {
public:
    void connect() override {
        cout << "连接到MySQL数据库" << endl;
    }
    
    void query(const string& sql) override {
        cout << "执行MySQL查询: " << sql << endl;
    }
};

6.2 多重继承与虚继承

菱形继承问题解决方案

class Animal {
public:
    virtual void breathe() {
        cout << "呼吸" << endl;
    }
};

// 虚继承
class LandAnimal : virtual public Animal {};
class WaterAnimal : virtual public Animal {};

// 两栖动物
class Amphibian : public LandAnimal, public WaterAnimal {
public:
    void breathe() override {
        cout << "两栖呼吸" << endl;
    }
};

七、实战案例:电脑组装系统

// 抽象CPU
class CPU {
public:
    virtual void calculate() = 0;
    virtual ~CPU() = default;
};

// Intel CPU实现
class IntelCPU : public CPU {
public:
    void calculate() override {
        cout << "Intel CPU 计算中..." << endl;
    }
};

// 抽象显卡
class GPU {
public:
    virtual void render() = 0;
    virtual ~GPU() = default;
};

// NVIDIA显卡实现
class NVIDIA_GPU : public GPU {
public:
    void render() override {
        cout << "NVIDIA GPU 渲染中..." << endl;
    }
};

// 电脑系统
class ComputerSystem {
public:
    ComputerSystem(CPU* cpu, GPU* gpu) 
        : cpu(cpu), gpu(gpu) {}
    
    void run() {
        cpu->calculate();
        gpu->render();
        cout << "系统运行中..." << endl;
    }
    
    ~ComputerSystem() {
        delete cpu;
        delete gpu;
    }

private:
    CPU* cpu;
    GPU* gpu;
};

int main() {
    // 组装高性能电脑
    ComputerSystem highEndPC(
        new IntelCPU(), 
        new NVIDIA_GPU()
    );
    highEndPC.run();
    
    return 0;
}


结 束 语

能够看到这里的观众老爷,无疑是对up的最大肯定和支持,在此恳求各位观众老爷能够多多点赞、收藏和关注。在这个合集中,未来将持续给大家分享关于C++的多种常见开发实用操作。未来也将继续分享各种实用干货。感谢大家支持!



你可能感兴趣的:(C++,语言系列(教程,+,实战),c++,类和对象)