首页 自动驾驶

C++ 面向对象:从 C 程序员的角度深度解读四大特性

分类:自动驾驶
字数: (6585)
阅读: (1064)
内容摘要:C++ 面向对象:从 C 程序员的角度深度解读四大特性,

作为一名从 C 语言一路走来的后端工程师,初次接触 C++ 的面向对象编程时,相信不少人都遇到过类似的问题:概念理解起来容易,但如何运用到实际项目中却一头雾水。本文旨在帮助 C 程序员,用熟悉的 C 语言思维去理解 C++ 的面向对象四大特性:封装、继承、多态和抽象。通过对比 C 语言的实现方式,让你彻底搞懂 C++ 的面向对象编程。

封装:从 struct 到 class 的演变

在 C 语言中,我们使用 struct 来组织数据,但数据和操作数据的函数是分离的。例如,一个简单的表示点的结构体:

// C 语言的 struct
typedef struct {
    int x;
    int y;
} Point;

// 操作 Point 的函数
void Point_print(Point p) {
    printf("Point(%d, %d)\n", p.x, p.y);
}

虽然 struct 可以将相关数据组织在一起,但无法限制对内部数据的访问。任何函数都可以直接修改 Pointxy 成员,这存在安全隐患。

C++ 中的 class 则提供了更强的封装性。通过访问控制修饰符(privateprotectedpublic),可以控制类成员的访问权限:

// C++ 的 class
class Point {
private:
    int x;
    int y;
public:
    Point(int x, int y) : x(x), y(y) {}
    void print() {
        std::cout << "Point(" << x << ", " << y << ")" << std::endl;
    }
    int getX() const { return x; } // 提供只读接口
    int getY() const { return y; } const { return y; }
    void setX(int x) { this->x = x; } // 提供修改接口
    void setY(int y) { this->y = y; }
};

在上面的 C++ 代码中,xy 成员被声明为 private,只能通过 public 的成员函数 getXgetYsetXsetY 来访问和修改。这样就实现了数据的隐藏和保护,提高了代码的健壮性。

C++ 面向对象:从 C 程序员的角度深度解读四大特性

这种封装性在大型项目中尤为重要。比如,在构建一个 Web 服务器时,我们可以将请求处理逻辑封装在一个类中,对外只暴露必要的接口,避免外部直接操作内部数据,提高系统的安全性。常见的如使用 Nginx 做反向代理,保护后端服务器,并通过配置控制并发连接数,保障服务器的稳定运行。

继承:代码复用的利器

继承允许我们创建一个新的类(子类),继承现有类(父类)的属性和方法。这避免了代码重复,提高了代码的复用性。

在 C 语言中,虽然没有直接的继承机制,但可以通过结构体嵌套和函数指针来实现类似的功能。

// C 语言模拟继承
typedef struct {
    int width;
    int height;
} Rectangle;

typedef struct {
    Rectangle rect;
    int radius;
} Circle;

void Rectangle_print(Rectangle r) {
    printf("Rectangle(width=%d, height=%d)\n", r.width, r.height);
}

void Circle_print(Circle c) {
    printf("Circle(width=%d, height=%d, radius=%d)\n", c.rect.width, c.rect.height, c.radius);
}

在 C++ 中,继承的实现更加简洁明了:

C++ 面向对象:从 C 程序员的角度深度解读四大特性
// C++ 继承
class Rectangle {
public:
    Rectangle(int width, int height) : width(width), height(height) {}
    void print() {
        std::cout << "Rectangle(width=" << width << ", height=" << height << ")" << std::endl;
    }
protected:
    int width;
    int height;
};

class Circle : public Rectangle {
public:
    Circle(int width, int height, int radius) : Rectangle(width, height), radius(radius) {}
    void print() {
        std::cout << "Circle(width=" << width << ", height=" << height << ", radius=" << radius << ")" << std::endl;
    }
private:
    int radius;
};

Circle 类继承了 Rectangle 类的 widthheight 属性,以及 print 方法。子类可以重写父类的方法(方法重写,override),实现不同的行为。

实际项目里,比如在开发游戏引擎时,可以创建一个基类 GameObject,包含所有游戏对象共有的属性和方法(如位置、旋转、渲染)。然后,可以派生出不同的子类,如 PlayerEnemyProp,它们都继承自 GameObject,并添加各自特有的属性和方法。这样做可以极大地减少代码量,提高开发效率。

多态:同一接口,不同行为

多态是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。C++ 通过虚函数来实现多态。

在 C 语言中,可以使用函数指针来实现类似的多态。

C++ 面向对象:从 C 程序员的角度深度解读四大特性
// C 语言模拟多态
typedef struct {
    void (*print)(void*);
    int type;
} Shape;

typedef struct {
    Shape base;
    int width;
    int height;
} Rectangle;

typedef struct {
    Shape base;
    int radius;
} Circle;

void Rectangle_print(void* r) {
    Rectangle* rect = (Rectangle*)r;
    printf("Rectangle(width=%d, height=%d)\n", rect->width, rect->height);
}

void Circle_print(void* c) {
    Circle* circle = (Circle*)c;
    printf("Circle(radius=%d)\n", circle->radius);
}

int main() {
    Rectangle rect = {{Rectangle_print, 1}, 10, 20};
    Circle circle = {{Circle_print, 2}, 5};

    Shape* shapes[] = {(Shape*)&rect, (Shape*)&circle};
    for (int i = 0; i < 2; i++) {
        shapes[i]->print(shapes[i]);
    }
    return 0;
}

C++ 中,虚函数的实现更加优雅:

// C++ 多态
class Shape {
public:
    virtual void print() {
        std::cout << "Shape\n";
    }
};

class Rectangle : public Shape {
public:
    void print() override {
        std::cout << "Rectangle\n";
    }
};

class Circle : public Shape {
public:
    void print() override {
        std::cout << "Circle\n";
    }
};

int main() {
    Shape* shapes[] = {new Rectangle(), new Circle()};
    for (int i = 0; i < 2; i++) {
        shapes[i]->print(); // 调用的是实际对象的 print 方法
    }
    return 0;
}

通过将 Shape 类的 print 方法声明为 virtual,子类可以重写该方法,并在运行时根据对象的实际类型调用相应的方法。这种多态性在处理异构对象集合时非常有用。

比如,在开发支付系统时,可以定义一个 Payment 接口,包含一个 pay 方法。然后,可以实现不同的支付方式,如 CreditCardPaymentPayPalPaymentWechatPayment,它们都实现了 Payment 接口的 pay 方法。这样,在处理支付请求时,可以根据用户的选择调用相应的支付方式,而无需关心具体的支付细节。

抽象:定义接口,隐藏实现

抽象是指从具体事物中提取出本质特征,忽略非本质特征。C++ 中,可以通过抽象类和接口来实现抽象。

C++ 面向对象:从 C 程序员的角度深度解读四大特性

抽象类是指包含纯虚函数的类。纯虚函数是指没有实现的虚函数,必须由子类来实现。

// C++ 抽象类
class AbstractClass {
public:
    virtual void doSomething() = 0; // 纯虚函数
    virtual ~AbstractClass() = default; // 虚析构函数
};

class ConcreteClass : public AbstractClass {
public:
    void doSomething() override {
        std::cout << "ConcreteClass is doing something\n";
    }
};

AbstractClass 类包含一个纯虚函数 doSomething,因此它是一个抽象类。抽象类不能被实例化,只能被继承。子类必须实现抽象类中的所有纯虚函数,才能被实例化。

在实际应用中,抽象类常用于定义接口,隐藏具体的实现细节。比如,可以定义一个 File 抽象类,包含 openreadwriteclose 等纯虚函数。然后,可以实现不同的文件类型,如 TextFileBinaryFile,它们都继承自 File 抽象类,并实现各自的文件操作方法。这样,在使用文件时,只需要关心 File 接口,而无需关心具体的实现细节。这个思路在文件服务器的构建中十分重要,也与诸如宝塔面板这类管理软件的运行息息相关。

总结:面向对象,C++ 的核心

从 C 到 C++ 的转变,不仅仅是语法的改变,更重要的是编程思想的转变。理解面向对象四大特性,能够帮助我们写出更模块化、更易维护、更可扩展的代码。希望本文能够帮助你更好地理解 C++ 的面向对象编程,并在实际项目中灵活运用。

C++ 面向对象:从 C 程序员的角度深度解读四大特性

转载请注明出处: DevOps小王子

本文的链接地址: http://m.acea2.store/blog/169559.SHTML

本文最后 发布于2026-04-24 05:57:32,已经过了3天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 蛋炒饭 23 小时前
    对于想从 C 转 C++ 的同学,这篇文章绝对是入门必读!
  • 随风飘零 6 天前
    写得真不错,用 C 语言的例子来对比理解 C++,思路很清晰!
  • 海带缠潜艇 6 天前
    多态那里的函数指针模拟实现,简直是灵魂!瞬间明白了 C++ 虚函数的本质。
  • 老实人 3 天前
    文章深入浅出,例子也都很实用,希望能多出一些这种高质量的技术文章!
  • 螺蛳粉真香 2 天前
    多态那里的函数指针模拟实现,简直是灵魂!瞬间明白了 C++ 虚函数的本质。