卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与语法

    • 介绍c++一下三大特性
    • 指针和引用的区别
    • 结构体和类的区别
    • 结构体与联合体的区别
      • 简要回答
      • 详细回答
      • 代码示例
      • 知识拓展
    • static关键字和const关键字的作用
    • extern C的作用
    • volatile关键字的作用
    • inline函数与宏的区别与优劣
    • auto和decltype的区别
    • sizeof和strlen的区别
    • 浮点数比较方法
    • 静态局部变量,全局变量,局部变量的特点,以及使用场景
    • C++中四种类型转换
  • 面向对象

  • STL 与容器

  • 内存管理

  • C++11 与现代 C++

  • 智能指针

  • 并发与 I/O

# c++中联合体和结构体的区别

面试时没有回答好问题是很正常的,被面试官质疑时,要有今天不会明天会的底气,面后做好复盘,不在同一道题目上跌倒第二次,今天就从 c++中联合体和结构体的区别 背起来

# 简要回答

在C++中,结构体(struct)和联合体(union)都是*用户定义的类型,但结构体所有成员同时存在且占用独立内存空间

而联合体所有成员共享同一内存空间,仅能存储一个成员的值。

C++11后,联合体可以包含非POD类型成员,并支持成员函数和特殊成员函数。

# 详细回答

  • C++中的结构体特性:

默认所有成员和继承都是public的类

支持成员函数、构造函数、析构函数还支持继承和多态

内存布局与C结构体类似,但可能更复杂(因虚函数表等)

C++11后支持成员初始化列表

  • C++中的联合体特性:

所有成员共享同一内存空间,C++11前只能包含POD类型成员,C++11后支持非POD类型,但需要显式管理生命周期

可以包含成员函数,包括构造函数和析构函数

不能继承也不能作为基类

不能包含虚函数或引用成员

  • 关键差异:

在访问控制方面:结构体默认使用public(可以修改为别的),而联合体成员总是public

结构体支持多态,而联合体不支持多态

生命周期管理:联合体需要显式管理非POD成员

结构体可以使用于模板,但是联合体受限很多

# 代码示例

#include <iostream>
#include <string>

// C++结构体示例(带成员函数)
struct Student {
    std::string name;
    int age;
    double score;

    // 成员函数
    void introduce() {
        std::cout << "我叫" << name << ",今年" << age << "岁,成绩" << score << std::endl;
    }

    // 构造函数
    Student(const std::string& n, int a, double s)
        : name(n), age(a), score(s) {}
};

// C++11联合体示例(含非POD类型)
union Variant {
    int i;
    double d;
    std::string s;  // 非POD类型

    // 构造函数
    Variant() : i(0) {}
    ~Variant() {}  // 需要自行管理字符串的生命周期

    // 成员函数
    void setInt(int val) { i = val; }
    void setString(const std::string& str) {
        new(&s) std::string(str);  // placement new
    }
    void destroyString() {
        s.~basic_string();  // 显式调用析构函数
    }
};

int main() {
    // 结构体使用
    Student stu("张三", 20, 90.5);
    stu.introduce();

    // 联合体使用
    Variant v;
    v.setInt(42);
    std::cout << "整数值: " << v.i << std::endl;

    v.setString("Hello");
    std::cout << "字符串值: " << v.s << std::endl;
    v.destroyString();

    // 查看大小
    std::cout << "结构体大小: " << sizeof(Student) << " 字节" << std::endl;
    std::cout << "联合体大小: " << sizeof(Variant) << " 字节" << std::endl;

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# 知识拓展

  • 知识图解

image

  • 适用场景

    1.C++结构体推荐场景

数据传输对象(DTO):在系统间传递数据

策略模式:作为策略的轻量级实现

模板元编程:作为编译期计算工具

接口简化:作为多个返回值的容器

内存布局控制:与硬件或网络协议交互

2.C++联合体推荐场景

变体类型:替代继承的轻量级方案

内存优化:嵌入式或高性能场景

二进制协议解析:解释网络数据包

类型转换:不同表示间的安全转换

  • 面试官很能追问

Q1: C++中结构体和类有什么区别?

A: 在C++中,结构体和类几乎相同,主要区别在于: 默认访问权限:结构体成员默认public,类默认private 默认继承权限:结构体继承默认public,类默认private 惯例:结构体通常用于数据聚合,类用于更复杂的抽象

Q2: 为什么C++11允许联合体包含非POD类型?

A: 为了增加灵活性,但需要开发者手动管理生命周期。因为联合体不知道当前活跃成员是谁,无法自动调用正确的构造函数/析构函数,所以需要: 使用placement new初始化非POD成员 显式调用析构函数 确保在销毁联合体前正确清理

Q3: 如何安全地使用包含std::string的联合体?

A: 需要: 提供构造函数正确初始化活跃成员 在析构函数中检查并正确销毁非POD成员 实现拷贝/移动操作时正确处理活跃成员 使用标记字段跟踪当前活跃成员 或者使用C++17的std::variant替代

Last Updated: 3/10/2026, 6:08:48 PM

← 结构体和类的区别 static关键字和const关键字的作用 →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪