news 2026/10/18 5:14:54

《Eigen入门》第 10 章 · const、作用域与命名空间

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《Eigen入门》第 10 章 · const、作用域与命名空间

这一章讲三个让代码更安全、更有条理的工具:const(保护数据)、作用域(变量在哪有效)、命名空间(避免名字冲突)。理解它们,代码质量和可读性会上一个台阶。

10.1 const:保护数据不被修改

const是"常量"的意思,用来声明"这个值不许改"。

const 变量

constintMAX=100;// MAX = 200; // 错误!const 变量不能修改

const 参数

函数参数加const,保证函数内不改这个参数:

voidprint(conststd::string&s){// s = "改它"; // 错误!s 是 const,不能改std::cout<<s<<std::endl;}

const 成员函数

类的方法加const,表示"这个方法不会修改对象的成员":

classRectangle{doublew,h;public:doublearea()const{// const 方法:只读,不改成员returnw*h;}};

const方法只能调用其他const方法,编译器会帮你把关。

核心思想:用const表达"我承诺不改",让编译器帮你守住承诺,把 bug 消灭在编译期。

10.2 作用域:变量在哪里有效

作用域(scope)决定了变量在代码的哪一段可见、可用。

花括号{}形成作用域

#include<iostream>intmain(){intx=10;// x 在整个 main 里有效{inty=20;// y 只在这个花括号内有效std::cout<<x<<" "<<y<<std::endl;// 都能访问}// std::cout << y; // 错误!y 已经出了作用域,不存在了return0;}

输出10 20。

变量在其声明的花括号{}内有效,出了花括号就"销毁"了。

全局变量 vs 局部变量

#include<iostream>intglobal=100;// 全局变量:整个文件都可见intmain(){intlocal=10;// 局部变量:只在 main 里可见std::cout<<global<<" "<<local<<std::endl;// 100 10}

建议:尽量用局部变量,少用全局变量。全局变量到处都能改,容易出 bug、难追踪。

10.3 命名空间:避免名字冲突

想象两个人都给变量起名PI,放在一起就冲突了。命名空间(namespace)就是给代码划"区域",隔离同名。

#include<iostream>namespacemathA{constdoublePI=3.14;}namespacemathB{constdoublePI=3.14159;}intmain(){std::cout<<mathA::PI<<std::endl;// 3.14std::cout<<mathB::PI<<std::endl;// 3.14159,同名不冲突}

用命名空间::名字精确指定要哪个。

using:简化前缀

std::写多了烦,可以用using:

// using 声明:只引入一个名字(推荐)usingstd::cout;cout<<"你好"<<std::endl;// using 指令:引入整个命名空间(省事但易冲突,慎用)usingnamespacestd;cout<<"直接用 cout"<<endl;

建议:初学时,尽量写全std::,养成好习惯。using namespace std;虽然省事,但在大项目里容易引发名字冲突。

std 和 Eigen 命名空间

现在你就懂了:

  • std::cout、std::string:标准库里的东西,都在std命名空间
  • Eigen::MatrixXd:Eigen 库的东西,都在Eigen命名空间

这就是为什么写 Eigen 代码时前面都有Eigen::。

10.4 头文件与多文件组织(了解)

真实项目不止一个 .cpp 文件,代码会拆分组织:

project/ ├── main.cpp # 主程序 ├── math_utils.h # 头文件:声明函数和类 └── math_utils.cpp # 源文件:实现

头文件(.h)放声明,源文件(.cpp)放实现。其他文件要使用时,#include头文件即可。

// math_utils.h —— 头文件#pragmaonce// 防止头文件被重复包含intadd(inta,intb);// 只声明,不实现
// math_utils.cpp —— 源文件#include"math_utils.h"intadd(inta,intb){// 实现returna+b;}
// main.cpp#include<iostream>#include"math_utils.h"// 引入自己的头文件intmain(){std::cout<<add(3,5)<<std::endl;// 8}
  • #pragma once防止同一个头文件被多次包含(避免重复定义)。
  • #include "..."(双引号)用于自己项目的头文件,#include <...>(尖括号)用于系统/库头文件。

这三个文件要一起编译——把两个 .cpp 都交给编译器,链接器才能找到add的实现:

g++-std=c++17 main.cpp math_utils.cpp-oapp.exe ./app.exe# 输出 8

漏掉math_utils.cpp会得到一个典型的链接期错误(编译能过,链接失败):

undefined reference to `add(int, int)'

MSVC 写法:cl /std:c++17 /EHsc /utf-8 main.cpp math_utils.cpp。文件更多时就不用手动列了,交给 CMake(附录 C.6~C.7)。

10.5 小结

  • const保护数据:const 变量、const 参数、const 方法。
  • 作用域:变量在声明它的{}内有效。
  • 命名空间:隔离同名,Eigen::、std::都是命名空间。
  • 多文件:头文件放声明,源文件放实现,#include引入。

下一章,学习动态内存与智能指针——在运行时灵活分配内存而不泄漏。


练习题

  1. 写一个const变量,尝试修改,看报什么错。
  2. 写两个命名空间,里面各放一个同名变量,分别访问。
  3. 写一个类,给它加一个const成员函数,说明它为什么不能修改成员。
  4. 把一个函数拆到头文件和源文件里,在 main 里调用它。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 5:13:00

VGG16迁移学习实战:小数据集图像分类微调全流程

1. 为什么选VGG16做迁移学习起点搞计算机视觉的人绕不开一个现实问题&#xff1a;自己手头的数据集往往小得可怜。几百张到几千张图片&#xff0c;想从零训练一个深度卷积网络&#xff0c;结果基本是训练集准确率冲到99%&#xff0c;验证集在60%附近反复横跳——过拟合得亲妈都…

作者头像 李华
网站建设 2026/10/18 5:10:43

站点指纹识别实战:判断建站程序、主题与支付接口

之前帮朋友处理过一个挺有意思的排查需求&#xff1a;对方给了一个链接&#xff0c;问我能不能看出这个资源站用的是什么建站程序、页面模板是哪家的、付费弹窗对接的又是哪类收款接口。我当时人还没点开页面&#xff0c;脑子里已经跑过一套完整的“站点指纹识别”流程。这类问…

作者头像 李华
网站建设 2026/10/18 5:10:24

KNN最优k值怎么选?用学习曲线一眼看穿过拟合与欠拟合

“k到底取多少才算最优&#xff1f;”这几乎是每个KNN新手都会撞上的第一堵墙。我当年拿着一份近5000条样本的客户回访数据&#xff0c;从k1一路配到k40&#xff0c;每改一次就重新fit、重新预测、重新算准确率&#xff0c;折腾了一下午自以为找到了“黄金k值”&#xff0c;结果…

作者头像 李华
网站建设 2026/10/18 5:08:48

AI智能体开发实战:用扣子平台从零搭建企业级应用

去年我开始认真做AI智能体方向的东西&#xff0c;前前后后用本地代码写了几个原型&#xff0c;能跑&#xff0c;但离“能用、敢上线”还有很大距离。后来接触了扣子这个AI智能体开发平台&#xff0c;很多长期让我头疼的事算是找到了解法。这篇文章不聊概念&#xff0c;就讲讲扣…

作者头像 李华
网站建设 2026/10/18 5:02:59

图表设计底层逻辑:信息分层与视觉动线规划

评审会议上&#xff0c;一张布满节点和线条的架构图被投到大屏幕上&#xff0c;讲解人口若悬河讲完&#xff0c;底下还是有人在问"所以这条链路到底是怎么走的"。问题不在讲的人&#xff0c;而在那张图。我在各种技术分享和项目复盘里见过太多这种场景&#xff1a;图…

作者头像 李华