C++面向对象编程:从基础到实战

C++面向对象编程:从基础到实战

一、基础篇:类与对象的核心概念

1.1 什么是面向对象编程?

面向对象编程(Object-Oriented Programming,简称OOP)是一种程序设计范型,它将数据和操作数据的方法绑定在一起,形成对象。在C++中,我们通过类(Class)来定义对象的蓝图,通过对象来实现具体的功能。

💡 核心思想:将现实世界中的事物抽象为对象,每个对象都有自己的属性和行为,对象之间通过消息传递进行交互。

1.2 类的定义与对象的创建

在C++中,类的定义通常分为两个部分:类声明和类实现。类声明包含类的成员变量和成员函数的声明,类实现包含成员函数的具体实现。

cpp 复制代码
// 类声明
class Student {
private:
    string name; // 姓名
    int age; // 年龄
    string id; // 学号

public:
    // 构造函数
    Student(string n, int a, string i);
    
    // 成员函数声明
    void display(); // 显示学生信息
    string getName(); // 获取姓名
    int getAge(); // 获取年龄
    string getId(); // 获取学号
    void setName(string n); // 设置姓名
    void setAge(int a); // 设置年龄
    void setId(string i); // 设置学号
};

// 类实现
Student::Student(string n, int a, string i) {
    name = n;
    age = a;
    id = i;
}

void Student::display() {
    cout << "姓名:" << name << endl;
    cout << "年龄:" << age << endl;
    cout << "学号:" << id << endl;
}

string Student::getName() {
    return name;
}

int Student::getAge() {
    return age;
}

string Student::getId() {
    return id;
}

void Student::setName(string n) {
    name = n;
}

void Student::setAge(int a) {
    age = a;
}

void Student::setId(string i) {
    id = i;
}

// 主函数
int main() {
    // 创建对象
    Student s1("张三", 18, "2023001");
    Student s2("李四", 19, "2023002");
    
    // 调用成员函数
    s1.display();
    cout << endl;
    s2.display();
    
    return 0;
}

💡 代码说明

  • class Student:定义了一个名为Student的类。
  • private:私有成员变量,只能在类内部访问。
  • public:公有成员函数,提供了访问和修改私有成员变量的接口。
  • Student::Student():构造函数,用于初始化对象。
  • Student::display():成员函数,用于显示学生信息。
  • main():主函数,创建了两个Student对象并调用了display()函数。

1.3 封装与访问控制

封装是面向对象编程的三大特性之一,它将数据和操作数据的方法封装在一个类中,并通过访问控制符来限制外部对数据的访问。在C++中,有三种访问控制符:public(公有)、private(私有)和protected(保护)。

cpp 复制代码
class Person {
private:
    string name; // 私有成员变量
    int age; // 私有成员变量

protected:
    string address; // 保护成员变量

public:
    // 构造函数
    Person(string n, int a, string addr);
    
    // 公有成员函数
    void display(); // 显示个人信息
    string getName(); // 获取姓名
    int getAge(); // 获取年龄
    string getAddress(); // 获取地址
    void setName(string n); // 设置姓名
    void setAge(int a); // 设置年龄
    void setAddress(string addr); // 设置地址
};

// 类实现
Person::Person(string n, int a, string addr) {
    name = n;
    age = a;
    address = addr;
}

void Person::display() {
    cout << "姓名:" << name << endl;
    cout << "年龄:" << age << endl;
    cout << "地址:" << address << endl;
}

string Person::getName() {
    return name;
}

int Person::getAge() {
    return age;
}

string Person::getAddress() {
    return address;
}

void Person::setName(string n) {
    name = n;
}

void Person::setAge(int a) {
    age = a;
}

void Person::setAddress(string addr) {
    address = addr;
}

💡 访问控制说明

  • private:私有成员变量和函数只能在类内部访问,外部无法直接访问。
  • public:公有成员变量和函数可以在类外部直接访问。
  • protected:保护成员变量和函数可以在类内部和子类中访问。

1.4 构造函数与析构函数

构造函数是类的一个特殊成员函数,用于初始化对象。当创建一个对象时,构造函数会自动调用。析构函数也是类的一个特殊成员函数,用于在对象销毁时释放资源。

cpp 复制代码
class Rectangle {
private:
    int width; // 宽度
    int height; // 高度

public:
    // 无参构造函数
    Rectangle();
    
    // 带参构造函数
    Rectangle(int w, int h);
    
    // 析构函数
    ~Rectangle();
    
    // 成员函数
    int getArea(); // 计算面积
    int getPerimeter(); // 计算周长
    void setWidth(int w); // 设置宽度
    void setHeight(int h); // 设置高度
    int getWidth(); // 获取宽度
    int getHeight(); // 获取高度
};

// 无参构造函数
Rectangle::Rectangle() {
    width = 0;
    height = 0;
    cout << "无参构造函数被调用" << endl;
}

// 带参构造函数
Rectangle::Rectangle(int w, int h) {
    width = w;
    height = h;
    cout << "带参构造函数被调用" << endl;
}

// 计算面积
int Rectangle::getArea() {
    return width * height;
}

// 计算周长
int Rectangle::getPerimeter() {
    return 2 * (width + height);
}

// 设置宽度
void Rectangle::setWidth(int w) {
    width = w;
}

// 设置高度
void Rectangle::setHeight(int h) {
    height = h;
}

// 获取宽度
int Rectangle::getWidth() {
    return width;
}

// 获取高度
int Rectangle::getHeight() {
    return height;
}

// 主函数
int main() {
    // 使用无参构造函数创建对象
    Rectangle rect1;
    cout << "矩形1的面积:" << rect1.getArea() << endl;
    cout << "矩形1的周长:" << rect1.getPerimeter() << endl;
    cout << endl;
    
    // 使用带参构造函数创建对象
    Rectangle rect2(5, 3);
    cout << "矩形2的面积:" << rect2.getArea() << endl;
    cout << "矩形2的周长:" << rect2.getPerimeter() << endl;
    
    return 0;
}

💡 代码说明

  • Rectangle():无参构造函数,用于初始化宽度和高度为0。
  • Rectangle(int w, int h):带参构造函数,用于初始化宽度和高度为指定值。
  • ~Rectangle():析构函数,用于在对象销毁时释放资源。
  • 在main()函数中,我们创建了两个Rectangle对象,一个使用无参构造函数,一个使用带参构造函数。

1.5 拷贝构造函数与赋值运算符

拷贝构造函数是类的一个特殊成员函数,用于创建一个新对象作为现有对象的副本。赋值运算符用于将一个对象的值赋给另一个对象。

cpp 复制代码
class Point {
private:
    int x; // x坐标
    int y; // y坐标

public:
    // 构造函数
    Point(int xVal = 0, int yVal = 0);
    
    // 拷贝构造函数
    Point(const Point& p);
    
    // 赋值运算符重载
    Point& operator=(const Point& p);
    
    // 成员函数
    void display(); // 显示坐标
    int getX(); // 获取x坐标
    int getY(); // 获取y坐标
    void setX(int xVal); // 设置x坐标
    void setY(int yVal); // 设置y坐标
};

// 构造函数
Point::Point(int xVal, int yVal) {
    x = xVal;
    y = yVal;
    cout << "构造函数被调用" << endl;
}

// 拷贝构造函数
Point::Point(const Point& p) {
    x = p.x;
    y = p.y;
    cout << "拷贝构造函数被调用" << endl;
}

// 赋值运算符重载
Point& Point::operator=(const Point& p) {
    if (this != &p) { // 避免自我赋值
        x = p.x;
        y = p.y;
    }
    cout << "赋值运算符被调用" << endl;
    return *this;
}

// 显示坐标
void Point::display() {
    cout << "坐标:(" << x << ", " << y << ")" << endl;
}

// 获取x坐标
int Point::getX() {
    return x;
}

// 获取y坐标
int Point::getY() {
    return y;
}

// 设置x坐标
void Point::setX(int xVal) {
    x = xVal;
}

// 设置y坐标
void Point::setY(int yVal) {
    y = yVal;
}

// 主函数
int main() {
    // 创建对象p1
    Point p1(10, 20);
    cout << "p1: ";
    p1.display();
    cout << endl;
    
    // 使用拷贝构造函数创建对象p2
    Point p2(p1);
    cout << "p2: ";
    p2.display();
    cout << endl;
    
    // 使用赋值运算符创建对象p3
    Point p3;
    p3 = p1;
    cout << "p3: ";
    p3.display();
    
    return 0;
}

💡 代码说明

  • Point(const Point& p):拷贝构造函数,用于创建一个新对象作为现有对象的副本。
  • Point& operator=(const Point& p):赋值运算符重载,用于将一个对象的值赋给另一个对象。
  • 在main()函数中,我们创建了三个Point对象,p2是p1的副本,p3通过赋值运算符获得p1的值。

1.6 静态成员变量与静态成员函数

静态成员变量是类的所有对象共享的变量,只有一个副本。静态成员函数可以在没有对象的情况下调用,它只能访问静态成员变量和静态成员函数。

cpp 复制代码
class Counter {
private:
    static int count; // 静态成员变量,用于计数
    int id; // 实例成员变量,用于标识对象

public:
    // 构造函数
    Counter();
    
    // 静态成员函数,用于获取计数
    static int getCount();
    
    // 成员函数,用于获取对象ID
    int getId();
};

// 初始化静态成员变量
int Counter::count = 0;

// 构造函数
Counter::Counter() {
    count++; // 每次创建对象时,计数加1
    id = count; // 为每个对象分配一个唯一的ID
}

// 静态成员函数,用于获取计数
int Counter::getCount() {
    return count;
}

// 成员函数,用于获取对象ID
int Counter::getId() {
    return id;
}

// 主函数
int main() {
    // 创建对象
    Counter c1;
    Counter c2;
    Counter c3;
    
    // 调用静态成员函数
    cout << "对象数量:" << Counter::getCount() << endl;
    
    // 调用成员函数
    cout << "c1的ID:" << c1.getId() << endl;
    cout << "c2的ID:" << c2.getId() << endl;
    cout << "c3的ID:" << c3.getId() << endl;
    
    return 0;
}

💡 代码说明

  • static int count:静态成员变量,用于计数对象的数量。
  • static int getCount():静态成员函数,用于获取对象的数量。
  • int Counter::count = 0:初始化静态成员变量。
  • 在main()函数中,我们创建了三个Counter对象,并调用了静态成员函数getCount()和成员函数getId()。

1.7 友元函数与友元类

友元函数是在类外部定义的函数,但可以访问类的私有成员和保护成员。友元类是一个类的所有成员函数都可以访问另一个类的私有成员和保护成员。

cpp 复制代码
class Point {
private:
    int x; // x坐标
    int y; // y坐标

public:
    // 构造函数
    Point(int xVal = 0, int yVal = 0);
    
    // 友元函数,用于计算两点之间的距离
    friend double distance(const Point& p1, const Point& p2);
    
    // 成员函数,用于显示坐标
    void display();
};

// 构造函数
Point::Point(int xVal, int yVal) {
    x = xVal;
    y = yVal;
}

// 友元函数,用于计算两点之间的距离
double distance(const Point& p1, const Point& p2) {
    int dx = p1.x - p2.x;
    int dy = p1.y - p2.y;
    return sqrt(dx * dx + dy * dy);
}

// 成员函数,用于显示坐标
void Point::display() {
    cout << "坐标:(" << x << ", " << y << ")" << endl;
}

// 主函数
int main() {
    // 创建对象
    Point p1(10, 20);
    Point p2(30, 40);
    
    // 调用友元函数
    double dist = distance(p1, p2);
    cout << "p1和p2之间的距离:" << dist << endl;
    
    // 调用成员函数
    cout << "p1: ";
    p1.display();
    cout << "p2: ";
    p2.display();
    
    return 0;
}

💡 代码说明

  • friend double distance(const Point& p1, const Point& p2):声明distance()函数为Point类的友元函数。
  • double distance(const Point& p1, const Point& p2):定义友元函数,计算两点之间的距离。
  • 在main()函数中,我们创建了两个Point对象,并调用了友元函数distance()和成员函数display()。

1.8 类的继承与派生

继承是面向对象编程的三大特性之一,它允许我们创建一个新类(派生类),继承现有类(基类)的属性和方法。派生类可以添加新的属性和方法,也可以重写基类的方法。

cpp 复制代码
// 基类
class Animal {
protected:
    string name; // 动物的名字

public:
    // 构造函数
    Animal(string n);
    
    // 成员函数
    virtual void makeSound(); // 发出声音
    virtual void move(); // 移动
};

// 基类构造函数
Animal::Animal(string n) {
    name = n;
}

// 基类成员函数
void Animal::makeSound() {
    cout << name << "发出声音" << endl;
}

void Animal::move() {
    cout << name << "移动" << endl;
}

// 派生类:Dog
class Dog : public Animal {
private:
    string breed; // 狗的品种

public:
    // 构造函数
    Dog(string n, string b);
    
    // 重写基类成员函数
    void makeSound() override;
    void move() override;
    
    // 派生类成员函数
    void fetch(); // 捡球
};

// 派生类构造函数
Dog::Dog(string n, string b) : Animal(n) {
    breed = b;
}

// 重写基类成员函数
void Dog::makeSound() {
    cout << name << "汪汪叫" << endl;
}

void Dog::move() {
    cout << name << "奔跑" << endl;
}

// 派生类成员函数
void Dog::fetch() {
    cout << name << "捡球" << endl;
}

// 派生类:Cat
class Cat : public Animal {
private:
    string color; // 猫的颜色

public:
    // 构造函数
    Cat(string n, string c);
    
    // 重写基类成员函数
    void makeSound() override;
    void move() override;
    
    // 派生类成员函数
    void climbTree(); // 爬树
};

// 派生类构造函数
Cat::Cat(string n, string c) : Animal(n) {
    color = c;
}

// 重写基类成员函数
void Cat::makeSound() {
    cout << name << "喵喵叫" << endl;
}

void Cat::move() {
    cout << name << "跳跃" << endl;
}

// 派生类成员函数
void Cat::climbTree() {
    cout << name << "爬树" << endl;
}

// 主函数
int main() {
    // 创建对象
    Dog dog("旺财", "金毛");
    Cat cat("咪咪", "白色");
    
    // 调用成员函数
    dog.makeSound();
    dog.move();
    dog.fetch();
    cout << endl;
    cat.makeSound();
    cat.move();
    cat.climbTree();
    
    return 0;
}

💡 代码说明

  • class Animal:定义了一个名为Animal的基类,包含name属性和makeSound()、move()方法。
  • class Dog : public Animal:定义了一个名为Dog的派生类,继承自Animal类,添加了breed属性和fetch()方法,并重写了makeSound()和move()方法。
  • class Cat : public Animal:定义了一个名为Cat的派生类,继承自Animal类,添加了color属性和climbTree()方法,并重写了makeSound()和move()方法。
  • virtual:关键字用于声明虚函数,允许在派生类中重写基类的方法。
  • override:关键字用于明确表示该方法是重写基类的方法,提高代码的可读性。

1.9 多态性与虚函数

多态性是面向对象编程的三大特性之一,它允许我们使用基类的指针或引用来调用派生类的方法。在C++中,我们通过虚函数来实现多态性。

cpp 复制代码
// 基类
class Shape {
protected:
    string name; // 形状的名字

public:
    // 构造函数
    Shape(string n);
    
    // 虚函数,用于计算面积
    virtual double getArea() = 0;
    
    // 虚函数,用于计算周长
    virtual double getPerimeter() = 0;
    
    // 成员函数,用于显示形状信息
    virtual void display();
};

// 基类构造函数
Shape::Shape(string n) {
    name = n;
}

// 基类成员函数
void Shape::display() {
    cout << "形状:" << name << endl;
    cout << "面积:" << getArea() << endl;
    cout << "周长:" << getPerimeter() << endl;
}

// 派生类:Circle(圆形)
class Circle : public Shape {
private:
    double radius; // 半径

public:
    // 构造函数
    Circle(string n, double r);
    
    // 重写基类虚函数
    double getArea() override;
    double getPerimeter() override;
};

// 派生类构造函数
Circle::Circle(string n, double r) : Shape(n) {
    radius = r;
}

// 重写基类虚函数
double Circle::getArea() {
    return 3.14159 * radius * radius;
}

double Circle::getPerimeter() {
    return 2 * 3.14159 * radius;
}

// 派生类:Rectangle(矩形)
class Rectangle : public Shape {
private:
    double width; // 宽度
    double height; // 高度

public:
    // 构造函数
    Rectangle(string n, double w, double h);
    
    // 重写基类虚函数
    double getArea() override;
    double getPerimeter() override;
};

// 派生类构造函数
Rectangle::Rectangle(string n, double w, double h) : Shape(n) {
    width = w;
    height = h;
}

// 重写基类虚函数
double Rectangle::getArea() {
    return width * height;
}

double Rectangle::getPerimeter() {
    return 2 * (width + height);
}

// 主函数
int main() {
    // 创建对象
    Circle circle("圆形", 5);
    Rectangle rectangle("矩形", 4, 6);
    
    // 使用基类指针调用派生类方法
    Shape* shape1 = &circle;
    Shape* shape2 = &rectangle;
    
    shape1->display();
    cout << endl;
    shape2->display();
    
    return 0;
}

💡 代码说明

  • virtual double getArea() = 0:声明纯虚函数,纯虚函数没有具体的实现,只有声明。包含纯虚函数的类称为抽象类,不能直接创建对象。
  • class Circle : public Shape:定义了一个名为Circle的派生类,继承自Shape类,实现了getArea()和getPerimeter()方法。
  • class Rectangle : public Shape:定义了一个名为Rectangle的派生类,继承自Shape类,实现了getArea()和getPerimeter()方法。
  • Shape* shape1 = &circle:使用基类指针指向派生类对象。
  • shape1->display():通过基类指针调用派生类的方法,实现了多态性。

二、进阶篇:面向对象编程的高级特性

2.1 抽象类与接口

抽象类是包含至少一个纯虚函数的类,不能直接创建对象。抽象类的主要作用是作为基类,定义接口,派生类必须实现抽象类中的纯虚函数。

cpp 复制代码
// 抽象类:Shape(形状)
class Shape {
protected:
    string name; // 形状的名字

public:
    // 构造函数
    Shape(string n);
    
    // 纯虚函数,用于计算面积
    virtual double getArea() = 0;
    
    // 纯虚函数,用于计算周长
    virtual double getPerimeter() = 0;
    
    // 成员函数,用于显示形状信息
    virtual void display();
};

// 基类构造函数
Shape::Shape(string n) {
    name = n;
}

// 基类成员函数
void Shape::display() {
    cout << "形状:" << name << endl;
    cout << "面积:" << getArea() << endl;
    cout << "周长:" << getPerimeter() << endl;
}

// 派生类:Circle(圆形)
class Circle : public Shape {
private:
    double radius; // 半径

public:
    // 构造函数
    Circle(string n, double r);
    
    // 重写基类纯虚函数
    double getArea() override;
    double getPerimeter() override;
};

// 派生类构造函数
Circle::Circle(string n, double r) : Shape(n) {
    radius = r;
}

// 重写基类纯虚函数
double Circle::getArea() {
    return 3.14159 * radius * radius;
}

double Circle::getPerimeter() {
    return 2 * 3.14159 * radius;
}

// 派生类:Rectangle(矩形)
class Rectangle : public Shape {
private:
    double width; // 宽度
    double height; // 高度

public:
    // 构造函数
    Rectangle(string n, double w, double h);
    
    // 重写基类纯虚函数
    double getArea() override;
    double getPerimeter() override;
};

// 派生类构造函数
Rectangle::Rectangle(string n, double w, double h) : Shape(n) {
    width = w;
    height = h;
}

// 重写基类纯虚函数
double Rectangle::getArea() {
    return width * height;
}

double Rectangle::getPerimeter() {
    return 2 * (width + height);
}

// 主函数
int main() {
    // 创建对象
    Circle circle("圆形", 5);
    Rectangle rectangle("矩形", 4, 6);
    
    // 使用基类指针调用派生类方法
    Shape* shape1 = &circle;
    Shape* shape2 = &rectangle;
    
    shape1->display();
    cout << endl;
    shape2->display();
    
    return 0;
}

💡 代码说明

  • class Shape:定义了一个抽象类,包含纯虚函数getArea()和getPerimeter()。
  • class Circle : public Shape:定义了一个名为Circle的派生类,实现了getArea()和getPerimeter()方法。
  • class Rectangle : public Shape:定义了一个名为Rectangle的派生类,实现了getArea()和getPerimeter()方法。
  • Shape* shape1 = &circle:使用基类指针指向派生类对象。
  • shape1->display():通过基类指针调用派生类的方法,实现了多态性。

2.2 虚析构函数

虚析构函数是在基类中声明的析构函数,用于在通过基类指针删除派生类对象时,正确地调用派生类的析构函数。

cpp 复制代码
// 基类
class Base {
public:
    // 构造函数
    Base() {
        cout << "基类构造函数被调用" << endl;
    }
    
    // 虚析构函数
    virtual ~Base() {
        cout << "基类析构函数被调用" << endl;
    }
};

// 派生类
class Derived : public Base {
private:
    int* data; // 指向动态分配的内存

public:
    // 构造函数
    Derived() {
        cout << "派生类构造函数被调用" << endl;
        data = new int[10];
    }
    
    // 析构函数
    ~Derived() {
        cout << "派生类析构函数被调用" << endl;
        delete[] data;
    }
};

// 主函数
int main() {
    // 创建派生类对象
    Base* base = new Derived();
    
    // 删除派生类对象
    delete base;
    
    return 0;
}

💡 代码说明

  • virtual ~Base():声明虚析构函数。
  • Derived():派生类构造函数,动态分配内存。
  • ~Derived():派生类析构函数,释放动态分配的内存。
  • 在main()函数中,我们使用基类指针创建了一个派生类对象,并通过基类指针删除该对象。由于基类的析构函数是虚函数,所以派生类的析构函数会被正确地调用。

2.3 多重继承与菱形继承问题

多重继承是指一个派生类继承自多个基类。菱形继承是指一个派生类继承自两个基类,而这两个基类又继承自同一个基类。

cpp 复制代码
// 基类
class Base {
protected:
    int x;

public:
    // 构造函数
    Base(int xVal) : x(xVal) {}
    
    // 成员函数
    virtual void display() {
        cout << "Base类的x:" << x << endl;
    }
};

// 派生类1
class Derived1 : public Base {
public:
    // 构造函数
    Derived1(int xVal) : Base(xVal) {}
    
    // 重写基类成员函数
    void display() override {
        cout << "Derived1类的x:" << x << endl;
    }
};

// 派生类2
class Derived2 : public Base {
public:
    // 构造函数
    Derived2(int xVal) : Base(xVal) {}
    
    // 重写基类成员函数
    void display() override {
        cout << "Derived2类的x:" << x << endl;
    }
};

// 派生类3(多重继承)
class Derived3 : public Derived1, public Derived2 {
public:
    // 构造函数
    Derived3(int x1, int x2) : Derived1(x1), Derived2(x2) {}
    
    // 成员函数
    void display() override {
        cout << "Derived3类的x1:" << Derived1::x << endl;
        cout << "Derived3类的x2:" << Derived2::x << endl;
    }
};

// 主函数
int main() {
    // 创建对象
    Derived3 derived3(10, 20);
    
    // 调用成员函数
    derived3.display();
    
    return 0;
}

💡 代码说明

  • class Base:定义了一个基类,包含x属性和display()方法。
  • class Derived1 : public Base:定义了一个派生类,继承自Base类,重写了display()方法。
  • class Derived2 : public Base:定义了一个派生类,继承自Base类,重写了display()方法。
cpp 复制代码
// 派生类3(多重继承)
class Derived3 : public Derived1, public Derived2 {
public:
    // 构造函数
    Derived3(int x1, int x2) : Derived1(x1), Derived2(x2) {}
    
    // 成员函数
    void display() override {
        cout << "Derived3类的x1:" << Derived1::x << endl;
        cout << "Derived3类的x2:" << Derived2::x << endl;
    }
};

// 主函数
int main() {
    // 创建对象
    Derived3 derived3(10, 20);
    
    // 调用成员函数
    derived3.display();
    
    return 0;
}

💡 代码说明

  • class Derived3 : public Derived1, public Derived2:定义了一个名为Derived3的派生类,继承自Derived1和Derived2类。
  • Derived3(int x1, int x2) : Derived1(x1), Derived2(x2):构造函数,调用Derived1和Derived2类的构造函数。
  • void display() override:重写display()方法,分别显示Derived1和Derived2类的x属性。

⚠️ 注意事项

  1. 多重继承会增加代码的复杂度,因此在实际开发中应该尽量避免使用多重继承。
  2. 如果必须使用多重继承,应该使用virtual继承来解决菱形继承问题。

2.4 虚继承与菱形继承问题的解决

虚继承是指在继承时使用virtual关键字,使得基类只会被继承一次,从而避免菱形继承问题。

cpp 复制代码
// 基类
class Base {
protected:
    int x;

public:
    // 构造函数
    Base(int xVal) : x(xVal) {}
    
    // 成员函数
    virtual void display() {
        cout << "Base类的x:" << x << endl;
    }
};

// 派生类1(虚继承)
class Derived1 : virtual public Base {
public:
    // 构造函数
    Derived1(int xVal) : Base(xVal) {}
    
    // 重写基类成员函数
    void display() override {
        cout << "Derived1类的x:" << x << endl;
    }
};

// 派生类2(虚继承)
class Derived2 : virtual public Base {
public:
    // 构造函数
    Derived2(int xVal) : Base(xVal) {}
    
    // 重写基类成员函数
    void display() override {
        cout << "Derived2类的x:" << x << endl;
    }
};

// 派生类3(多重继承)
class Derived3 : public Derived1, public Derived2 {
public:
    // 构造函数
    Derived3(int xVal) : Base(xVal), Derived1(xVal), Derived2(xVal) {}
    
    // 成员函数
    void display() override {
        cout << "Derived3类的x:" << x << endl;
    }
};

// 主函数
int main() {
    // 创建对象
    Derived3 derived3(10);
    
    // 调用成员函数
    derived3.display();
    
    return 0;
}

💡 代码说明

  • class Derived1 : virtual public Base:定义了一个派生类,使用虚继承继承自Base类。
  • class Derived2 : virtual public Base:定义了一个派生类,使用虚继承继承自Base类。
  • Derived3(int xVal) : Base(xVal), Derived1(xVal), Derived2(xVal):构造函数,调用Base类的构造函数,然后调用Derived1和Derived2类的构造函数。
  • void display() override:重写display()方法,显示x属性。

2.5 运算符重载

运算符重载是指对已有的运算符进行重新定义,以支持自定义类型的操作。在C++中,我们可以通过函数重载和运算符重载来实现自定义类型的操作。

cpp 复制代码
// 类:Vector(向量)
class Vector {
private:
    double x; // x坐标
    double y; // y坐标

public:
    // 构造函数
    Vector(double xVal = 0, double yVal = 0) : x(xVal), y(yVal) {}
    
    // 运算符重载:+
    Vector operator+(const Vector& v) const {
        return Vector(x + v.x, y + v.y);
    }
    
    // 运算符重载:-
    Vector operator-(const Vector& v) const {
        return Vector(x - v.x, y - v.y);
    }
    
    // 运算符重载:*
    Vector operator*(double scalar) const {
        return Vector(x * scalar, y * scalar);
    }
    
    // 运算符重载:<<
    friend ostream& operator<<(ostream& os, const Vector& v) {
        os << "(" << v.x << ", " << v.y << ")";
        return os;
    }
};

// 主函数
int main() {
    // 创建对象
    Vector v1(10, 20);
    Vector v2(30, 40);
    
    // 使用运算符重载
    Vector v3 = v1 + v2;
    Vector v4 = v1 - v2;
    Vector v5 = v1 * 2;
    
    // 输出结果
    cout << "v1:" << v1 << endl;
    cout << "v2:" << v2 << endl;
    cout << "v3:" << v3 << endl;
    cout << "v4:" << v4 << endl;
    cout << "v5:" << v5 << endl;
    
    return 0;
}

💡 代码说明

  • class Vector:定义了一个名为Vector的类,包含x和y属性。
  • Vector operator+(const Vector& v) const:运算符重载,实现了向量的加法操作。
  • Vector operator-(const Vector& v) const:运算符重载,实现了向量的减法操作。
  • Vector operator*(double scalar) const:运算符重载,实现了向量的标量乘法操作。
相关推荐
m0_706653236 分钟前
C++编译期数组操作
开发语言·c++·算法
故事和你9116 分钟前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
Bruk.Liu22 分钟前
(LangChain实战2):LangChain消息(message)的使用
开发语言·langchain
qq_4232339028 分钟前
C++与Python混合编程实战
开发语言·c++·算法
m0_7155753440 分钟前
分布式任务调度系统
开发语言·c++·算法
csbysj20201 小时前
选择(Selectable)
开发语言
CSDN_RTKLIB1 小时前
简化版unique_ptr说明其本质
c++
naruto_lnq1 小时前
泛型编程与STL设计思想
开发语言·c++·算法
:Concerto1 小时前
JavaSE 注解
java·开发语言·sprint
m0_748708052 小时前
C++中的观察者模式实战
开发语言·c++·算法