尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Effective C++学习笔记

Effective C++学习笔记
📅 发布时间:2026/6/26 20:12:32

一.视C++为一个语言联邦

融合了多种编程思维方式

C++ 同时支持四种编程范式(paradigms)

procedural-based(过程式)
object-based(基于对象)
object-oriented(面向对象)
generics(泛型)

这四种范式不是“可选”的,而是交织在一起的,你必须都懂,才能看懂别人写的代码,甚至才能看懂标准库。

范式举例特点
过程式std::sort(arr, arr+n)像 C 一样,函数+数据分离
基于对象std::string s; s.size();有封装,但无继承多态
面向对象class Derived : public Base继承、多态、虚函数
泛型template<typename T> void foo(T t)编译期多态、模板元编程

二.尽量以const,enum,inline替换#define

1.静态成员变量:只有一份存储,不属于任何对象→ 编译器必须在一个翻译单元里给它真正的内存定义。

规则是:

  • 声明放在类体内(带static)。

  • 定义(即分配存储)放在类外且只能出现一次;通常放在.cpp文件。

  • 例外:如果它是整型或枚举类型的 const 静态成员,并且初始化值是常量表达式,C++11 起允许在类内直接给初值,此时可省略类外定义——只要代码里从不取它的地址或绑定引用即可。一旦有人&Foo::value或把它传给const int&,就必须再补一份类外定义。

//.hpp class Foo { static int a; // ① 非 const:类内只能声明 static const int b = 42; // ② const 整型:类内给初值 static constexpr int c = 5; // ③ constexpr:类内直接是定义 }; //.cpp int Foo::a = 0; // ① 必须定义 // const int Foo::b = 42; // ② 如果没人取地址,可省;否则要这一行

2.静态成员函数

  • 没有this指针,也不占对象空间,不存在“初始化”概念。

  • 声明与定义都可以写在类内或类外,不会重复链接冲突。

三.尽可能用const

1.const vector<int>::itrrator iter = xxx;//iter的作用像T* const,指向不可变,内容可变

vector<int>::const_iterator citer = xxx;//iter的作用像const T*,指向可变,内容不可变

2.const成员函数

成员函数版本通行证颜色对数据成员的“默认权限”
非 const 成员函数绿色通行证读写均可
const 成员函数红色通行证只读;写操作一律当成“违章”
变量身份绿色函数(非 const)红色函数(const)典型错误提示
① 非 const 成员变量读 ✅ 写 ✅读 ✅ 写 ❌“assignment of member … in read-only object”
② const 成员变量读 ✅ 写 ❌读 ✅ 写 ❌同上;两种函数都不能写
③ mutable 成员变量读 ✅ 写 ✅读 ✅ 写 ✅无;mutable 是“红证特区”
④ static 成员变量(不论是否 const)读写均不受成员函数 const 性影响;它们不属于任何对象,通行证颜色管不到它们。

常见迷思一次澄清

  • “const 成员函数只能访问 const 成员变量?”
    → 错!任何成员都能访问,只是不能写非 const、非 mutable 的成员。

  • “非 const 成员函数不能读 const 成员变量?”
    → 错!读永远允许,写才受限制。

  • “我把对象定义成const Demo obj;后,还能调非 const 成员函数吗?”
    → 不能。对象本身持红色通行证,只能调红色成员函数。

3.在const和non-const成员函数中避免重复

non-const函数内部调用const成员函数,为避免重复调用,需要将Text&使用static_cast转换const Text&,最后返回值使用const_cast移除const。

四.确定对象被使用前已被初始化

1.永远在使用对象(变量)之前将他初始化,对于无任何成员的内置类型,必须手动完成,对于以外的东西,初始化责任落在构造函数中,确保每一个构造函数都将对象的每一个成员初始化,注意别混淆复制与初始化

2.成员初值列进行初始化,成员初始化顺序,基类最先然后是继承类,class的成员变量总是以其声明次序被初始化

3.不同编译单元内定义的non-local static对象的初始化次序

解决“跨编译单元 non-local static 对象初始化顺序未定义”问题的黄金法则:

把每一个 non-local static 都变成 local static,并靠函数接口返回引用——即 Singleton 模式的核心手法。

“跨文件全局变量顺序不可控?包一层函数,把 non-local static 变 local static——初始化顺序立刻由自己掌控。”


为什么 local static 能救命

  1. C++ 保证:首次遇到控制流时才会初始化 local static 变量;

  2. 初始化顺序由第一次调用函数的顺序决定,而调用顺序是你写的代码,可见、可控;

  3. 同时满足“全局唯一 + 延迟构造 + 线程安全”(C++11 起,local static 初始化是线程安全的)。


最简洁的替代模板

// 原全局变量 // extern int g_config; // 别的 cpp 用 // 替换后 int& getConfig() // 返回引用,保证全局唯一 { static int config = readFromFile(); // 第一次调用才初始化 return config; }

任何文件用它:

int v = getConfig(); // 不再直接依赖 g_config

带类版本的通用骨架

class Config { public: static Config& instance() { // 返回引用 static Config inst; // local static return inst; } int value() const { return val_; } void setValue(int v) { val_ = v; } private: Config() : val_(readFromFile()) {} int val_; };
Config::instance().setValue(42); int x = Config::instance().value();

相关新闻

  • 推荐阅读:现代Python爬虫技术的演进与实战技巧
  • 爬虫到底难在哪里?
  • 基于SpringBoot+Vue的实习生管理系统管理系统设计与实现【Java+MySQL+MyBatis完整源码】

最新新闻

  • 用互联网黑话提需求,AI 真能听懂吗?
  • AMD硬件调试工具深度解析:掌握处理器性能优化的完整指南
  • 基于企业微信iPad协议的自动化能力建设方案
  • 东莞翻译公司 法语财报翻译方法
  • Web安全信息收集实战:七步法构建目标技术画像与精准渗透
  • AlienFX Tools终极指南:从零开始掌握Alienware灯光与风扇控制

日新闻

  • Qwen2.5-Turbo百万上下文实战指南:百炼平台长文本处理全解析
  • 怎么监控对标账号更新,2026年作者监控工作流,5款深度对比
  • EdgeRemover:专业级Windows Edge浏览器管理工具,彻底解决顽固软件卸载难题

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号