2. C++基础语法强化

好,咱们进入第二章。说实话,从C语言到C++,很多人觉得就是多了个class。其实不然。真正让你写出工程级代码的,是那些看似不起眼的基础语法强化。今天我就带你逐个过一遍。

核心知识点一览:bool类型、const关键字、引用、内联函数、函数重载。这五个东西,每一个都是C++工程化的基石。

C++基础语法强化 bool 类型 const 关键字 引用 内联函数 函数重载 五个知识点,环环相扣,缺一不可

2.1 bool类型——C语言里没有的"真与假"

C语言里判断真假,用的是int。0代表假,非0代表真。这其实挺别扭的。你想想看,一个函数返回int,你根本不知道它到底想表达什么——是状态码?还是布尔值?

C++引入了真正的bool类型。就两个值:true和false。干净利落。

bool isConnected = true;
bool isTimeout = false;

if (isConnected) {
    // 连接成功
}

我的习惯:所有表示"是否"的变量,一律用bool。别再用int了。我在代码审查时看到过太多用int当布尔用的bug——有人把返回值3当成了true,结果逻辑全乱套。

bool类型在内存里只占1个字节。但要注意,它和int之间可以隐式转换,不过我个人建议你尽量避免这种混用。

2.2 const关键字——给变量上把锁

const,说白了就是"只读"。你告诉编译器:这个变量,我初始化之后就不改了。你敢改?编译器报错给你看。

const的用法其实挺多的,我列几个常见的:

  • const修饰普通变量:值不可变
  • const修饰指针:指向的内容不可变,或者指针本身不可变
  • const修饰函数参数:函数内不会修改传入的参数
  • const修饰成员函数:该函数不会修改对象的状态
const int MAX_SIZE = 1024;  // 常量,不可修改

void printData(const char* str) {  // 保证不修改str指向的内容
    // str[0] = 'A';  // 编译错误!
    printf("%s", str);
}

class MyClass {
public:
    int getValue() const {  // const成员函数
        return m_value;
    }
private:
    int m_value;
};

我曾经踩过的坑:const修饰指针时,const在星号左边和右边含义完全不同。const int* p 表示指向的内容不可变,int* const p 表示指针本身不可变。我当年刚学的时候搞混过,结果线上代码出了个隐蔽的bug,排查了一整天。

记住一个原则:能用const的地方,尽量用。它不仅是语法约束,更是给代码阅读者的承诺。

2.3 引用——指针的"优雅替身"

引用是什么?说白了就是变量的别名。你给它起个小名,叫啥都行,但指向的是同一个人。

int a = 10;
int& ref = a;  // ref是a的引用
ref = 20;      // 现在a也变成了20

引用和指针最大的区别是什么?引用一旦绑定,就不能再指向别的变量了。而且引用不能为空。这就少了很多空指针的烦恼。

我项目中用得最多的地方,就是函数参数传递。特别是传递大对象时,用引用可以避免拷贝开销。

void processLargeData(const std::vector<int>& data) {
    // 用const引用,既高效又安全
    // 不会拷贝整个vector,也不会意外修改它
}

关键区别:引用 vs 指针

特性 引用 指针
是否可为空 否 是
能否重新绑定 否 是
语法简洁性 高(直接使用) 低(需要解引用)
安全性 高 低(容易野指针)

2.4 内联函数——用空间换时间

函数调用是有开销的。压栈、跳转、返回...这些操作虽然快,但如果你在一个循环里调用几百万次,那开销就不可忽视了。

内联函数就是解决这个问题的。用inline关键字告诉编译器:把函数体直接插入到调用处,省去调用开销。

inline int max(int a, int b) {
    return a > b ? a : b;
}

// 调用时,编译器可能直接展开为:
// int result = (x > y) ? x : y;

我的建议:内联函数适合那种函数体很小(比如一两行)、调用频繁的场景。千万别把几百行的大函数写成inline,那会导致代码膨胀,反而降低性能。我曾经见过有人把整个业务逻辑写成inline,结果编译出来的二进制文件大了好几倍。

注意,inline只是建议,不是命令。编译器有权忽略你的inline请求。比如递归函数、虚函数,通常不会被内联。

2.5 函数重载——同名不同人

函数重载,就是同一个函数名,参数不同。C语言不支持这个,你得自己起不同的名字,比如max_int、max_float、max_double...累不累?

C++允许你定义多个同名函数,只要参数列表不同就行。编译器会根据你传入的参数,自动选择正确的版本。

int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

// 调用时:
int sum1 = add(3, 5);        // 调用int版本
double sum2 = add(3.14, 2.5); // 调用double版本

注意:函数重载只看参数列表,不看返回值类型。你不能写两个同名函数,参数一样,只是返回值不同——编译器会报错,因为它不知道你想调用哪个。

函数重载让代码更直观。你想想看,printf为什么能打印各种类型?其实就是重载了。C++的cout也是这个道理。

小结

这五个基础语法强化,每一个单独看都不难。但组合起来,就能写出更安全、更高效、更易读的代码。我个人觉得,从C到C++的转变,不是学会多少新语法,而是养成一种"工程化"的思维习惯。

嗯,今天就先聊到这儿。这些内容你消化一下,后面我们会用它们来构建更复杂的工程结构。