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

C++ 类与对象全面剖析:构造函数深化与静态成员特性

深入探讨了 C++ 类与对象中的构造函数初始化列表,解释了 const 成员变量、引用成员变量及自定义类型成员变量为何必须使用初始化列表的原因,以确保初始化的唯一性。同时涵盖了类中的静态成员、友元函数与友元类、内部类及匿名对象等知识点。重点在于理解初始化列表对于确保唯一初始化的必要性。

极客工坊发布于 2026/3/30更新于 2026/10/2598 浏览
C++ 类与对象全面剖析:构造函数深化与静态成员特性

在这里插入图片描述

一、再探构造函数

在之前的文章中我们大致将构造函数讲完了,但是还有一个比较重要的知识点当时没有讲到,因为如果把这部分内容加上去,会让前面的内容难度变得非常高,所以这部分内容放到这里来讲。

接下来进入今天的正题,我们今天要补充的内容就是构造函数中的'初始化列表',它可以帮我们对成员变量进行初始化,我们还是先来看看它的语法格式 (刚开始学可能看起来怪怪的,熟悉了就好了),如下:

class Date {
 public:
  //不使用初始化列表
  Date(int year = 2025, int month = 1, int day = 1) {
   _year = year;
   _month = month;
   _day = day;
  }
  //使用初始化列表
  Date(int year = 2025, int month = 1, int day = 1):_year(year),_month(month),_day(day) {
   //在花括号中 (函数体中) 可以正常执行其它代码,这里就不演示了
  }
 private:
  int _year;
  int _month;
  int _day;
};

在上面的代码中,有两个构造函数,一个不使用初始化列表和一个使用了初始化列表,在这里它们的作用都是一样的,就是根据用户传来的年月日对当前对象进行初始化。

那么既然上面的代码中,无论是否使用了初始化列表,两个构造函数的作用都相同,而且这个初始化列表还这么丑,它到底有什么不同之处呢?接下来我们就正式介绍初始化列表。

初始化列表非常重要,有 3 类成员变量必须使用初始化列表进行初始化,如果不使用初始化列表就会报错,它们分别是 const 成员变量、引用成员变量以及自定义类型成员变量。那么为什么这 3 类成员变量就必须使用初始化列表进行初始化呢?

其中 const 成员变量以及引用成员变量比较特殊,它们都只能初始化一次,如果我们将其写在构造函数内部进行初始化会有一定的歧义,比如 const 成员变量只能初始化一次,往后这个成员变量的值就不能修改了,如果它在函数体出现两次,该选择哪个值作为它的结果。

而引用对象也是,只能初始化一次,往后只能修改引用对象的值,而不能修改引用对象的指向,如果在构造函数函数体中出现了两次,最终该选择哪个变量作为它的引用对象呢?我们来看如下伪代码:

class A {
 public:
  //构造
  A(int& a, int& b) {
   //如果写在函数体内,编译器最终应该选择 a 还是选择 4 这个值
   _a = a;
   _a = 4;
   //_b 又应该是谁的引用?会产生歧义
   _b = b;
   _b = a;
  }
 private:
  const int _a;
  int& _b;
};

所以针对这两类比较特殊的成员变量,C++ 就设计了初始化列表,供这种只能初始化一次的成员变量进行初始化,如果使用上面的方式进行初始化编译器就会直接报错,所以初始化列表确保了初始化的唯一性,如下:

class A {
 public:
  A(int& a, int& b):_a(a),_b(b) {}
 private:
  const int _a;
  int& _b;
};

这就是为什么 const 成员变量和引用成员变量必须使用初始化列表进行初始化的原因,那么为什么自定义类型也要使用初始化列表进行初始化呢?其实跟上面两个的原因差不多,我们慢慢来分析,首先在有默认构造的情况下,编译器会自动调用这个自定义类型的默认构造,如下:

class B {
 public:
  B(int b = 10) {
   _b = b;
  }
 private:
  Date _d;
  int _b;
};
int main() {
  B b;
  return 0;
}

在这个例子中,类 B 中既有内置类型,又有自定义类型,B 中只对内置类型作了处理,编译器也不会报错,因为编译器默认会去调用这个自定义类型的默认构造对这个自定义类型的成员变量作初始化,我们调试来看看:

目录

  1. 一、再探构造函数

更多推荐文章

查看全部
  • Web 应用架构与常见安全漏洞解析
  • 基于 LLaMA-Factory 的 LLM DPO 训练实战
  • F5 刷新时,浏览器前端究竟发生了什么?
  • Redis Hash 类型详解
  • Linux 进程通信核心原理与实战:匿名管道、命名管道、进程池
  • Cursor 中配置与使用 MCP 服务的实战指南
  • Milvus 实战:Attu 可视化安装与 Python 整合指南
  • 命令行大模型上下文协议(MCP)交互工具 MCPHost 实践
  • 利用 AI 快速构建 Windows 18-HD19 风格 CSS 组件库
  • RabbitMQ 事务机制详解与 Spring 配置实践
  • HTTP 代理 IP 地址列表
  • 飞书 OpenClaw 机器人 HTTP 401 Invalid Authentication 报错排查
  • VsCode 远程 Copilot 调用 Claude Agent 报“无效请求”:参数配置排查与修复
  • 前缀和算法实战:和为 K 的子数组与和可被 K 整除的子数组
  • Spring AI Alibaba 快速入门指南
  • FLAC3D 边坡地震稳定性动力分析:基线校正与模拟实现
  • C++ 红黑树:原理、旋转与完整实现
  • C++ STL 容器:基于红黑树模拟实现 map 和 set
  • Ubuntu 24.04 使用 Docker Compose 本地部署 Whisper 语音识别服务
  • 快速选择算法实战:求解数组第 K 大元素与最小 K 个数

相关免费在线工具

  • 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