为了账号安全,请及时绑定邮箱和手机立即绑定

C++面向对象资料入门教程

概述

本文介绍了C++面向对象的基础概念,包括类和对象的基本理解、成员变量与成员函数、构造函数与析构函数。文章还详细讲解了封装、继承和多态性等重要特性,并提供了多个示例代码来帮助理解。此外,文中还探讨了面向对象编程的设计原则及其应用,为读者提供了全面的C++面向对象编程知识。

C++面向对象基础概念

面向对象编程是现代软件开发的重要基石之一,C++作为一门强大的编程语言,全面支持面向对象的编程范式。本文将介绍C++中面向对象的基础概念,包括类和对象的基本理解、成员变量与成员函数、以及构造函数与析构函数。

类和对象的基本理解

在C++中,类(Class)是对象的蓝图,它定义了一组相关的变量(成员变量)和函数(成员函数),这些变量和函数共同描述了对象的状态和行为。对象(Object)则是类的一个具体实例,它包含了类定义的数据成员和成员函数的具体值。

// 定义一个简单的类
class Car {
public:
    // 成员变量
    int year;
    std::string make;
    std::string model;

    // 成员函数
    void displayInfo() {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    // 创建一个Car对象
    Car myCar;
    myCar.year = 2020;
    myCar.make = "Toyota";
    myCar.model = "Camry";

    // 调用成员函数
    myCar.displayInfo();

    return 0;
}

成员变量与成员函数

成员变量(Member Variables)是类中定义的数据成员,用来存储对象的状态。成员函数(Member Functions)是类定义中的函数,用来描述对象的行为或者状态变化。

class Car {
public:
    int year;
    std::string make;
    std::string model;

    void setYear(int y) {
        year = y;
    }

    void setMake(std::string m) {
        make = m;
    }

    void setModel(std::string mod) {
        model = mod;
    }

    void displayInfo() {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    Car myCar;
    myCar.setMake("Toyota");
    myCar.setModel("Camry");
    myCar.setYear(2020);

    myCar.displayInfo();

    return 0;
}

构造函数与析构函数

构造函数(Constructor)是一种特殊的成员函数,用于初始化新创建的对象。它在对象创建时自动调用,名称与类名相同,没有返回类型。

析构函数(Destructor)是一种特殊的成员函数,用于清理和释放对象使用的资源。它在对象被销毁之前自动调用,名称前加一个波浪线(~)。

class Car {
public:
    int year;
    std::string make;
    std::string model;

    // 构造函数
    Car(int y, std::string m, std::string mod) {
        year = y;
        make = m;
        model = mod;
    }

    // 析构函数
    ~Car() {
        std::cout << "Car object is being destroyed." << std::endl;
    }

    void displayInfo() {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    {
        Car myCar(2020, "Toyota", "Camry");
        myCar.displayInfo();
    }  // 析构函数在这里被自动调用

    return 0;
}

封装

封装是面向对象编程中一个重要的概念,它通过将对象的内部实现细节隐藏起来,只暴露必要的接口,从而增加程序的安全性和可维护性。C++中,封装是通过访问权限来实现的。

私有、保护、公有访问权限

在C++中,成员变量和成员函数可以通过访问权限来声明。这些访问权限包括私有(Private)、保护(Protected)和公共(Public)。

  • 私有(Private):只能在类的内部访问,不可从类的外部访问。
  • 保护(Protected):只能在类及其派生类内部访问。
  • 公有(Public):可以被任何访问到该类的对象所访问。
class Car {
private:
    int year;
    std::string make;
    std::string model;

public:
    Car(int y, std::string m, std::string mod) : year(y), make(m), model(mod) {}

    void setYear(int y) {
        year = y;
    }

    void setMake(std::string m) {
        make = m;
    }

    void setModel(std::string mod) {
        model = mod;
    }

    void displayInfo() {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    Car myCar(2020, "Toyota", "Camry");
    myCar.displayInfo();

    // 尝试修改私有变量
    myCar.year = 2010;  // 编译错误,year为私有成员变量

    myCar.setYear(2010);  // 正确,通过公有成员函数修改私有变量
    myCar.displayInfo();

    return 0;
}

作用域解析运算符

作用域解析运算符(::)主要用于访问类中的成员变量和成员函数。它可以在不同的作用域中解析成员,比如在类的内部和外部。

class Car {
private:
    int year;
    std::string make;
    std::string model;

public:
    Car(int y, std::string m, std::string mod) : year(y), make(m), model(mod) {}

    void setYear(int y) {
        ::year = y;
    }

    void setMake(std::string m) {
        ::make = m;
    }

    void setModel(std::string mod) {
        ::model = mod;
    }

    void displayInfo() {
        ::std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    Car myCar(2020, "Toyota", "Camry");
    myCar.displayInfo();

    // 使用作用域解析运算符访问成员变量和成员函数
    ::Car::setYear(myCar, 2010);
    myCar.displayInfo();

    return 0;
}

继承

继承是面向对象编程中的另一个核心概念,它允许一个类(子类或派生类)继承另一个类(基类或父类)的属性和行为。这样可以实现代码的重用和扩展。

单继承和多继承

单继承是指一个子类只能有一个直接基类,而多继承是指一个子类可以有多个直接基类。

class Vehicle {
public:
    int year;
    std::string make;
    std::string model;

    Vehicle(int y, std::string m, std::string mod) : year(y), make(m), model(mod) {}

    void displayInfo() {
        std::cout << "Vehicle: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

class Car : public Vehicle {
public:
    Car(int y, std::string m, std::string mod) : Vehicle(y, m, mod) {}

    void displayInfo() {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    Car myCar(2020, "Toyota", "Camry");
    myCar.displayInfo();

    return 0;
}

多继承示例:

class Engine {
public:
    int horsepower;

    Engine(int hp) : horsepower(hp) {}

    void displayInfo() {
        std::cout << "Engine: " << horsepower << " horsepower" << std::endl;
    }
};

class Car : public Vehicle, public Engine {
public:
    Car(int y, std::string m, std::string mod, int hp) : Vehicle(y, m, mod), Engine(hp) {}

    void displayInfo() {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
        std::cout << "Engine: " << horsepower << " horsepower" << std::endl;
    }
};

int main() {
    Car myCar(2020, "Toyota", "Camry", 200);
    myCar.displayInfo();

    return 0;
}

虚函数与纯虚函数

虚函数(Virtual Function)是一种允许动态绑定的成员函数。在基类中声明虚函数,派生类可以覆盖这些虚函数,以提供更具体的实现。纯虚函数(Pure Virtual Function)是一种特殊的虚函数,它没有具体的实现,但要求派生类必须实现这些函数。

class Vehicle {
public:
    int year;
    std::string make;
    std::string model;

    Vehicle(int y, std::string m, std::string mod) : year(y), make(m), model(mod) {}

    virtual void displayInfo() {
        std::cout << "Vehicle: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

class Car : public Vehicle {
public:
    Car(int y, std::string m, std::string mod) : Vehicle(y, m, mod) {}

    void displayInfo() override {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    Vehicle *myVehicle = new Car(2020, "Toyota", "Camry");
    myVehicle->displayInfo();

    return 0;
}

纯虚函数示例:

class Engine {
public:
    int horsepower;

    Engine(int hp) : horsepower(hp) {}

    virtual void displayInfo() = 0;  // 纯虚函数
};

class GasEngine : public Engine {
public:
    GasEngine(int hp) : Engine(hp) {}

    void displayInfo() override {
        std::cout << "Gas Engine: " << horsepower << " horsepower" << std::endl;
    }
};

class ElectricEngine : public Engine {
public:
    ElectricEngine(int hp) : Engine(hp) {}

    void displayInfo() override {
        std::cout << "Electric Engine: " << horsepower << " horsepower" << std::endl;
    }
};

int main() {
    Engine *engine1 = new GasEngine(200);
    engine1->displayInfo();

    Engine *engine2 = new ElectricEngine(300);
    engine2->displayInfo();

    return 0;
}

多态性

多态性(Polymorphism)是面向对象编程中的一个关键特性,它允许通过基类指针或引用调用派生类的成员函数。多态性分为动态绑定和静态绑定。

动态与静态绑定

静态绑定(Static Binding)在编译时确定调用哪个函数,而动态绑定(Dynamic Binding)在运行时确定调用哪个函数。

动态绑定示例:

class Vehicle {
public:
    int year;
    std::string make;
    std::string model;

    Vehicle(int y, std::string m, std::string mod) : year(y), make(m), model(mod) {}

    virtual void displayInfo() {
        std::cout << "Vehicle: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

class Car : public Vehicle {
public:
    Car(int y, std::string m, std::string mod) : Vehicle(y, m, mod) {}

    void displayInfo() override {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    Vehicle *myVehicle = new Car(2020, "Toyota", "Camry");
    myVehicle->displayInfo();

    return 0;
}

静态绑定示例(编译时绑定):

class Vehicle {
public:
    int year;
    std::string make;
    std::string model;

    Vehicle(int y, std::string m, std::string mod) : year(y), make(m), model(mod) {}

    void displayInfo() {
        std::cout << "Vehicle: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

class Car : public Vehicle {
public:
    Car(int y, std::string m, std::string mod) : Vehicle(y, m, mod) {}

    void displayInfo() {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    Car myCar(2020, "Toyota", "Camry");
    myCar.displayInfo();

    return 0;
}

虚函数的使用

虚函数允许通过基类指针或引用调用派生类的成员函数,从而实现动态绑定。

class Vehicle {
public:
    int year;
    std::string make;
    std::string model;

    Vehicle(int y, std::string m, std::string mod) : year(y), make(m), model(mod) {}

    virtual void displayInfo() {
        std::cout << "Vehicle: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

class Car : public Vehicle {
public:
    Car(int y, std::string m, std::string mod) : Vehicle(y, m, mod) {}

    void displayInfo() override {
        std::cout << "Car: " << make << " " << model << ", Year: " << year << std::endl;
    }
};

int main() {
    Vehicle *myVehicle = new Car(2020, "Toyota", "Camry");
    myVehicle->displayInfo();

    return 0;
}

虚拟与接口类

虚拟基类(Virtual Base Class)可以解决多继承中的重复继承问题,而接口类(Interface Class)是一种特殊的类,它定义了一组纯虚函数,提供了一组规范化的接口。

抽象类与接口类的应用

抽象类(Abstract Class)是一种不能直接实例化的类,它通常包含一个或多个纯虚函数。接口类是一种特殊的抽象类,它仅包含纯虚函数,没有数据成员。

class Engine {
public:
    virtual void displayInfo() = 0;
};

class GasEngine : public Engine {
public:
    int horsepower;

    GasEngine(int hp) : horsepower(hp) {}

    void displayInfo() override {
        std::cout << "Gas Engine: " << horsepower << " horsepower" << std::endl;
    }
};

class ElectricEngine : public Engine {
public:
    int horsepower;

    ElectricEngine(int hp) : horsepower(hp) {}

    void displayInfo() override {
        std::cout << "Electric Engine: " << horsepower << " horsepower" << std::endl;
    }
};

int main() {
    Engine *engine1 = new GasEngine(200);
    engine1->displayInfo();

    Engine *engine2 = new ElectricEngine(300);
    engine2->displayInfo();

    return 0;
}

虚拟基类示例:

class Base {
public:
    virtual void displayInfo() = 0;
};

class Derived1 : virtual public Base {
public:
    void displayInfo() override {
        std::cout << "Derived1" << std::endl;
    }
};

class Derived2 : virtual public Base {
public:
    void displayInfo() override {
        std::cout << "Derived2" << std::endl;
    }
};

class Derived3 : public Derived1, public Derived2 {
public:
    void displayInfo() override {
        Derived1::displayInfo();
        Derived2::displayInfo();
    }
};

int main() {
    Derived3 obj;
    obj.displayInfo();

    return 0;
}

面向对象编程设计原则

面向对象编程的设计原则是确保软件的可维护性和可扩展性,这些原则包括单一职责原则、开闭原则、里氏替换原则、接口隔离原则、依赖倒置原则和责任链原则。

单一职责原则(SRP)

单一职责原则是指一个类应该只有一个引起它变化的原因。这意味着一个类应该只有一个功能,避免多个职责混合在一起。

class Car {
public:
    void drive() {
        std::cout << "Driving the car." << std::endl;
    }

    void park() {
        std::cout << "Parking the car." << std::endl;
    }
};

class ParkingSystem {
public:
    void parkCar(Car car) {
        std::cout << "Parking car in the system." << std::endl;
    }
};

int main() {
    Car myCar;
    myCar.drive();
    myCar.park();

    ParkingSystem parkingSystem;
    parkingSystem.parkCar(myCar);

    return 0;
}

开闭原则(OCP)

开闭原则是指软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着在不修改现有代码的情况下,应该能够扩展类的功能。

class Vehicle {
public:
    virtual void drive() = 0;
};

class Car : public Vehicle {
public:
    void drive() override {
        std::cout << "Driving the car." << std::endl;
    }
};

class Motorcycle : public Vehicle {
public:
    void drive() override {
        std::cout << "Driving the motorcycle." << std::endl;
    }
};

int main() {
    Vehicle *car = new Car();
    car->drive();

    Vehicle *motorcycle = new Motorcycle();
    motorcycle->drive();

    return 0;
}

里氏替换原则(LSP)

里氏替换原则是指子类对象应该能够替换基类对象,而不影响程序的正确性。这意味着派生类对象可以在任何基类对象出现的地方使用。

class Shape {
public:
    virtual double area() = 0;
};

class Rectangle : public Shape {
public:
    int width;
    int height;

    Rectangle(int w, int h) : width(w), height(h) {}

    double area() override {
        return width * height;
    }
};

class Circle : public Shape {
public:
    int radius;

    Circle(int r) : radius(r) {}

    double area() override {
        return 3.14 * radius * radius;
    }
};

int main() {
    std::vector<Shape*> shapes;
    shapes.push_back(new Rectangle(4, 5));
    shapes.push_back(new Circle(3));

    for (Shape* shape : shapes) {
        std::cout << "Area: " << shape->area() << std::endl;
    }

    return 0;
}

接口隔离原则(ISP)

接口隔离原则是指不应该强迫客户端依赖它们不需要的接口。这意味着应该将接口分解成更小的、更具体的接口,以满足特定客户端的需求。

class Keyboard {
public:
    void typeText() {
        std::cout << "Typing text." << std::endl;
    }
};

class Mouse {
public:
    void click() {
        std::cout << "Clicking the mouse." << std::endl;
    }
};

class Computer {
public:
    Keyboard keyboard;
    Mouse mouse;

    void useKeyboard() {
        keyboard.typeText();
    }

    void useMouse() {
        mouse.click();
    }
};

int main() {
    Computer computer;
    computer.useKeyboard();
    computer.useMouse();

    return 0;
}

依赖倒置原则(DIP)

依赖倒置原则是指抽象不应该依赖于细节,细节应该依赖于抽象。这意味着应该通过接口或抽象类而不是具体类来实现依赖关系。

class Engine {
public:
    virtual void start() = 0;
    virtual void stop() = 0;
};

class GasEngine : public Engine {
public:
    void start() override {
        std::cout << "Starting gas engine." << std::endl;
    }

    void stop() override {
        std::cout << "Stopping gas engine." << std::endl;
    }
};

class ElectricEngine : public Engine {
public:
    void start() override {
        std::cout << "Starting electric engine." << std::endl;
    }

    void stop() override {
        std::cout << "Stopping electric engine." << std::endl;
    }
};

class Car {
private:
    Engine* engine;

public:
    Car(Engine* e) : engine(e) {}

    void startEngine() {
        engine->start();
    }

    void stopEngine() {
        engine->stop();
    }
};

int main() {
    Engine* gasEngine = new GasEngine();
    Car gasCar(gasEngine);
    gasCar.startEngine();
    gasCar.stopEngine();

    Engine* electricEngine = new ElectricEngine();
    Car electricCar(electricEngine);
    electricCar.startEngine();
    electricCar.stopEngine();

    return 0;
}

责任链原则(Chain of Responsibility)

责任链原则是指请求可以在责任链上传递,直到有一个对象处理它为止。这意味着请求可以通过多个处理者传递,直到找到一个合适的处理者来处理它。

class Handler {
public:
    virtual void handleRequest() = 0;
};

class ConcreteHandler1 : public Handler {
public:
    void handleRequest() override {
        std::cout << "ConcreteHandler1 handling request." << std::endl;
    }
};

class ConcreteHandler2 : public Handler {
public:
    void handleRequest() override {
        std::cout << "ConcreteHandler2 handling request." << std::endl;
    }
};

class Client {
private:
    Handler* handler1;
    Handler* handler2;

public:
    Client(Handler* h1, Handler* h2) : handler1(h1), handler2(h2) {}

    void setNextHandler(Handler* nextHandler) {
        handler2 = nextHandler;
    }

    void request() {
        handler1->handleRequest();
        handler2->handleRequest();
    }
};

int main() {
    ConcreteHandler1 handler1;
    ConcreteHandler2 handler2;
    Client client(&handler1, &handler2);

    client.request();
    client.setNextHandler(&handler2);
    client.request();

    return 0;
}

通过以上示例和代码演示,我们可以看到C++语言中面向对象编程的各个重要概念和设计原则。这些概念不仅增强了代码的组织和复用,还使得代码更加灵活和易于扩展。通过遵循这些原则,可以编写出更加健壮和可维护的程序。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消