一、C++与面向对象概述

大家好,我是你们这门课的老师。今天咱们聊聊C++的起源,以及它和C语言那点事儿。说实话,我刚开始学编程那会儿,也觉得这些历史背景挺枯燥的。但后来在实际项目中踩过几次坑,才明白——不了解语言的来龙去脉,写代码就容易「知其然不知其所以然」。

1.1 C++语言发展史

C++诞生于上世纪80年代初。它的父亲叫Bjarne Stroustrup,当时在贝尔实验室工作。他原本是想给C语言加点「面向对象」的料,结果一不小心搞出了个新语言。

我简单梳理一下关键节点:

年份 事件
1979年 Bjarne开始研究「带类的C」
1983年 正式命名为C++(++是C的自增运算符)
1998年 第一个国际标准C++98发布
2011年 C++11发布,现代C++的起点
2014/2017/2020 后续标准持续更新

为什么叫C++?说白了,就是「C语言的升级版」。++运算符在C里表示自增1,所以C++这个名字,意思就是「比C更进一步」。

1.2 C++与C语言的关系

这个问题我经常被问到:「老师,我学过C,学C++是不是很容易?」

嗯,对,也不全对。

C++几乎兼容C语言的所有语法。你写的C代码,大部分可以直接拿到C++编译器里跑。但反过来不行——C++多了很多C没有的东西,比如类、继承、多态、异常处理等等。

我个人习惯把C++看作「C语言的超集 + 面向对象 + 泛型编程 + 标准库」。你想想看,C语言能做的事,C++都能做;但C++能做的事,C语言做起来就费劲了。

核心区别一句话:C是面向过程的,C++是面向对象的。C关注「怎么做」,C++关注「谁来做」。

1.3 面向对象编程的四大特性

面向对象编程(OOP)有四个核心特性。我当年面试的时候,面试官让我用一句话概括,我说:「封装、继承、多态、抽象,缺一不可。」

咱们一个一个来看。

封装

封装就是把数据和操作数据的方法打包在一起,对外只暴露接口,隐藏内部实现。我在项目中遇到过一个问题:有个同事把类的成员变量全写成public,结果到处都能改,最后查bug查了三天。嗯,这就是没做好封装的代价。

继承

继承允许你基于已有的类创建新类。子类可以复用父类的代码,也可以扩展自己的功能。说白了,就是「儿子继承老子的家产,还能自己再赚点」。

多态

多态的意思是「同一个接口,多种实现」。比如你定义一个「画图」函数,圆形类去画圆,方形类去画方。调用的时候不用管具体是什么形状,统一调用「画图」就行。我曾经用多态重构过一个项目,代码量直接砍掉40%。

抽象

抽象就是只关注「做什么」,不关注「怎么做」。比如你开车,只需要知道方向盘、油门、刹车怎么用,不需要知道发动机内部怎么工作的。抽象让我们能站在更高的层次思考问题。

我的建议:刚开始学的时候,别急着把四个特性全搞透。先理解封装和继承,再慢慢啃多态和抽象。一口吃不成胖子。

1.4 第一个C++程序:Hello World

好了,理论说够了,咱们来写点代码。第一个程序,永远是Hello World。

#include <iostream>
using namespace std;

int main() {
    cout << "Hello, World!" << endl;
    return 0;
}

这段代码很简单,但我还是想拆开讲讲:

  • #include <iostream>:引入输入输出流库。没有它,你就没法用cout。
  • using namespace std;:告诉编译器,我们用的是标准命名空间。后面会细说。
  • int main():程序的入口函数。每个C++程序都必须有一个main函数。
  • cout << "Hello, World!" << endl;:输出字符串到控制台。endl表示换行。
  • return 0;:告诉操作系统,程序正常结束。

注意:C++是大小写敏感的。你把main写成Main,编译器会直接报错。我曾经有个学生,找了半小时bug,结果就是大小写写错了。

1.5 命名空间(namespace)的基本使用

命名空间是C++用来解决命名冲突的机制。你想想看,一个项目里几百个文件,万一两个文件里定义了同名的函数怎么办?命名空间就是给这些名字加个「姓氏」。

基本用法:

namespace MySpace {
    int value = 42;
    void show() {
        cout << "Value: " << value << endl;
    }
}

int main() {
    MySpace::show();  // 通过 :: 访问命名空间中的成员
    return 0;
}

这里::叫作用域解析运算符。它的作用就是告诉编译器:「我要找的是MySpace里的show,不是别的show。」

你也可以用using关键字偷个懒:

using namespace MySpace;
// 之后就可以直接写 show() 了

但我个人建议:在头文件里尽量不要用using namespace std;。为什么?因为头文件会被很多源文件包含,你这一using,相当于把整个std命名空间暴露给所有包含它的文件,很容易引发命名冲突。我在项目里吃过这个亏,后来就养成了「头文件里不用using」的习惯。

避坑指南:如果你只用到std里的cout,可以写成using std::cout;,这样只引入cout,不会把整个std都拉进来。更安全,也更清晰。

知识体系总览

下面这张图,是我自己画的本章知识结构。你可以把它当作一张「地图」,学完本章后对照着检查自己有没有遗漏。

C++面向对象入门 C++语言发展史 C++与C语言的关系 四大特性 封装 继承 多态 抽象 第一个C++程序 命名空间namespace 打好基础,后面才能飞得起来

好了,第一章的内容就到这儿。记住,C++不是一门「学完就能写所有东西」的语言,但它是一门「学好了就能写出高质量代码」的语言。咱们慢慢来,不着急。


公众号:蓝海资料掘金营,微信deep3321