跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

C++ 的关键基础:命名空间、引用与函数重载

C++ 通过命名空间隔离标识符,避免全局名字冲突;输入输出采用流式操作自动识别类型,可关同步提升性能。缺省参数提供默认值,半缺省须从右向左连续。函数重载允许多个同名函数,依据参数类型或个数区分,但返回值不同不算重载,缺省参数需避免歧义。引用是别名,必须初始化且绑定不可变,常用于传参避免拷贝。指针和引用在内存占用、初始化要求等方面有明确差异。内联函数在调用处展开,适合短小函数替代宏。nullptr 是专门的空指针字面量,解决了 NULL 既是 0 又是指针的歧义。

人间失格发布于 2026/6/12更新于 2026/8/2420 浏览
C++ 的关键基础:命名空间、引用与函数重载

命名空间

名字冲突的痛苦

C 和 C++ 里,变量、函数和类名默认都堆在全局作用域里,冲突是家常便饭。一个叫做 rand 的整型变量就可能跟标准库里的 rand() 过不去。

#include <stdio.h>
#include <stdlib.h>

int rand = 6;

int main() {
    printf("%d", rand);
}

命名空间就是为了把名字圈进独立的小隔间,互不干扰。C++ 的做法:

#include <stdio.h>

namespace m {
    int rand = 6;
}

int main() {
    printf("%d", m::rand);
}

定义与隔离

用 namespace 关键字划出一个域,里面放变量、函数或类型,跟全局隔开。不同域里同名是完全合法的。编译器查找名字时只看你所在的域(局部、全局、命名空间或类)。局部域和全局域还影响生命周期,命名空间域和类域则不影响。

namespace m {
    int a = 6;
    int Add(int a, int b) {
        return a + b;
    }
    struct Node {
        struct Node* next;
        int val;
    };
}

支持嵌套,同一个命名空间可以散在不同文件里自动合并。标准库的东西基本都关在 std 里。

namespace m {
    namespace n {
        int a = 0;
        int b = 9;
    }
    int c = 6;
}

使用方式

默认查找只在局部和全局进行,所以要用命名空间成员有三种路子:

  1. 每次访问时带上命名空间前缀,比如 std::cout —— 最推荐。
  2. 用 using 把单个名字拉进当前作用域:using m::a;。无冲突时很方便。
  3. 一把梭 using namespace std;,小练习可以,工程里容易污染全局,慎用。

输入输出

C++ 的 IO 通过流库实现,std::cin 和 std::cout 分别是 istream 和 ostream 的对象,<< 是流插入,>> 是流提取。

#include <iostream>

int main() {
    int a = 0;
    double b = 0;
    std::cin >> a >> b;
    std::cout << a << " " << b << std::endl;
    return 0;
}

好处是不用手动指定类型格式,编译器自己识别。如果对 IO 性能要求极高(比如算法竞赛),可以关掉同步流提速:

ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);

缺省参数

函数声明或定义时给参数一个默认值,调用时不传就用它。全缺省和半缺省都可以。

#include <iostream>
using namespace std;

int Add(int a = 1, int b = 2) {
    return a + b;
}

int main() {
    cout << Add(4, 3) << endl; // 7
    cout << Add() << endl;     // 3
    return 0;
}

半缺省参数必须从右往左连续给出,调用时从左往右依次传实参。声明和定义分离时,缺省值只能出现在一处,通常留在声明里。

函数重载

同一作用域内允许函数同名,只要参数不同(个数或类型)。C 没这能力。

按参数类型区分

void Add(int a, int b) { cout << a + b << endl; }
void Add(double a, double b) { cout << a + b << endl; }

按参数个数区分

void fuc() { cout << "haha" << endl; }
void fuc(int a) { cout << "hehe" << endl; }

按参数类型顺序区分

void fuc(int a, char b) { cout << "haha" << endl; }
void fuc(char b, int a) { cout << "hehe" << endl; }

容易踩的坑

  • 返回值类型不同不算重载,调用时挑不出来。
  • 缺省参数可能造成歧义,比如 f() 和 f(int a = 10),编译器不知道你叫谁。可以用命名空间隔离:
namespace m {
    void f1(int a = 10) { cout << "f(int a)" << endl; }
}
// 调用时 f1() 或 m::f1() 清清楚楚

引用

别名而已

引用是另一个名字,不占额外内存。

int a = 0;
int& b = a; // b 就是 a
int& c = b; // c 也是 a

特性

  • 必须初始化,定义时就绑死。
  • 绑了谁就永远是它,赋值只是修改值,不会换绑。

常见用处

传参和返回时避免拷贝,或者直接修改原对象。比如写个栈,用引用传进去:

#include <iostream>
#include <cstdlib>
using namespace std;

typedef int STDataType;
typedef struct Stack {
    STDataType* a;
    int top;
    int capacity;
} ST;

void STInit(ST& rs, int n = 4) {
    rs.a = (STDataType*)malloc(n * sizeof(STDataType));
    rs.top = 0;
    rs.capacity = n;
}

void STPush(ST& rs, STDataType x) {
    if (rs.capacity == rs.top) {
        int newcapacity = (rs.capacity == 0 ? 4 : rs.capacity * 2);
        STDataType* ptr = (STDataType*)realloc(rs.a, sizeof(STDataType) * newcapacity);
        if (ptr == NULL) {
            perror("realloc");
            return;
        }
        rs.a = ptr;
        rs.capacity = newcapacity;
    }
    rs.a[rs.top++] = x;
}

int& STTop(ST& rs) {
    return rs.a[rs.top - 1];
}

void STDestroy(ST& rs) {
    if (rs.a == NULL) return;
    free(rs.a);
    rs.a = nullptr;
    rs.capacity = rs.top = 0;
}

int main() {
    ST rs;
    STInit(rs);
    STPush(rs, 1);
    STPush(rs, 2);
    cout << STTop(rs) << endl;
    STTop(rs) = 10; // 通过引用直接改栈顶
    cout << STTop(rs) << endl;
    STDestroy(rs);
    return 0;
}

const 引用

  • 只能拿 const 引用去引用 const 对象。
  • 隐式转换产生的临时对象具有常性,只能用 const 引用接住,顺便防止意外修改。
double a = 1.23;
const int& b = a; // 必须 const

指针和引用对比

特性引用指针
内存别名,不额外占空间存放地址,占空间
初始化必须初始化建议初始化,非强制
指向可变不可变可变
访问直接需解引用
sizeof引用类型大小地址大小
安全性较高,少野引用容易出现空/野指针

inline 内联

在调用处展开函数体,省去栈帧开销,适合短小且频繁调用的函数。递归或复杂的函数通常会被编译器无视。

inline void Swap(int& a, int& b) {
    int tmp = a;
    a = b;
    b = tmp;
}

比起 C 的宏,inline 不丢类型检查,调试也舒服。声明和定义最好放一起,分开放不同文件可能导致链接找不到。

nullptr

问题

用 NULL 调重载函数时,它可能是个 0,结果跑进了参数为整型的版本,而不是指针版本。

原因

C++ 里 NULL 可能是字面常量 0 或 (void*)0,类型推断时容易搞偏。

解决

C++11 搞出 nullptr,只认指针类型,不能隐式转成整数,彻底消除歧义。

void fuc(int* a) { cout << "pointer" << endl; }
void fuc(int a) { cout << "int" << endl; }

int main() {
    fuc(nullptr); // 明明白白走指针版本
    return 0;
}

目录

  1. 命名空间
  2. 名字冲突的痛苦
  3. 定义与隔离
  4. 使用方式
  5. 输入输出
  6. 缺省参数
  7. 函数重载
  8. 按参数类型区分
  9. 按参数个数区分
  10. 按参数类型顺序区分
  11. 容易踩的坑
  12. 引用
  13. 别名而已
  14. 特性
  15. 常见用处
  16. const 引用
  17. 指针和引用对比
  18. inline 内联
  19. nullptr
  20. 问题
  21. 原因
  22. 解决
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • GitHub Agent HQ 实战:Copilot Pro 接入与代码库全生命周期管理
  • Linux 下 NFS 服务端与客户端的安装配置及挂载指南
  • OpenClaw Gateway 命令与交互指南
  • Stable Diffusion 3.5 创意工作流与云端 GPU 加速方案
  • RAG 技术在内容推荐中的实践应用
  • Python 3.12.0 Windows 安装与环境配置指南
  • Office 区域不支持 Copilot 的解决方法
  • 基于 Dify 与 Qwen3-VL 的低代码视觉智能应用构建
  • 基于 llama.cpp 部署 Qwen3-14B-Claude-4.5-Opus-High-Reasoning-Distill-GGUF 模型
  • Docker 部署配置全流程:Windows 与 Linux 环境
  • Whisper 语音识别完整指南:从入门到应用
  • ClawdBot 免配置方案:Docker 集成 Whisper tiny 与 PaddleOCR
  • Z-Image-Turbo AI 绘画技术解析与性能实测
  • Linux 多线程基础:线程与进程的关系及特性
  • Python Scrapy 爬虫核心配置与管道实战
  • LAM-YOLO: 无人机小目标检测模型的光照遮挡注意力机制
  • 计算机网络基础定义与资源交换机制
  • AI 产品经理指南:面试百人后的角色认知与转型路径
  • AI 编程助手价格与体验对比:Claude Code vs 国产替代
  • 链表算法实战:相交节点查找与回文结构判断

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online