C++内存布局以及常用关键字

news2025/2/24 12:22:07

C++内存布局以及常用关键字

C++的内存空间

代码存储区域:常量区、代码区、静态区(全局区)、堆区、栈区

栈区向下增长,堆区向上增长。栈由系统管理,没有内存碎片,每个元素之间都是连续的,大小比较小,8k,可以修改系统参数,堆区存储动态开辟的变量。

还有一个内核空间,但是它不与用户直接交互(内核区)。

C++的内存空间

常用关键字

static

修饰局部变量:局部变量的存储区域改变、变为静态区,生命周期改为程序结束才销毁。

修饰全局变量:全局变量只能在本文件中访问,不能在其它文件中访问, extern 外部声明也不可以。

修饰成员变量:静态成员变量不属于实体的类对象,要在类外初始化

修饰成员函数:静态函数属于类不属于类对象 需要通过类作用域调用 函数无this指针(静态成员函数仅能访问静态的数据成员,不能访问非静态的数据成员,也不能访问非静态的成员函数)

#define

带参数的宏定义可以减少函数调用的开销,在运行时只是简单的展开。

#include <iostream>
#define SQUARE(x) ((x) * (x))

int main() {
    int a = 5;
    std::cout << "Square of a: " << SQUARE(a) << std::endl;
    std::cout << "Square of a+1: " << SQUARE(a + 1) << std::endl;
    return 0;
}

代码会被展开为:

std::cout << "Square of a: " << ((a) * (a)) << std::endl;
std::cout << "Square of a+1: " << ((a + 1) * (a + 1)) << std::endl;

同样逻辑使用函数实现:

inline int square(int x) {
    return x * x;
}

虽然 inline 函数也可能避免函数调用开销,但其行为是在编译阶段由编译器决定;而宏定义是在预处理阶段直接展开。因此,宏展开比函数调用更加简单直接。

const

申明一个常量,在编译期间可以进行类型检查,确保其值在程序运行期间不能被修改。

它还可以应用于指针、函数形参和成员函数等不同场景。

基本用法示例

  1. 定义常量

    const int a = 10; // 定义一个整型常量
    a = 20;           // 错误,尝试修改常量的值
    

    在编译阶段,如果试图修改 a 的值,会报错:
    “assignment of read-only variable ‘a’”

  2. 指针中的 constconst 在指针上下文中非常灵活,具体含义取决于其位置(需要注意理解哦:

    • 指针指向的值不可变

      const int* ptr = &a; // 指针指向的内容是只读的
      *ptr = 20;           // 错误
      ptr = &b;            // 正确,可以修改指针本身
      
    • 指针本身不可变

      int* const ptr = &a; // 指针本身是常量,不能指向其他地址
      *ptr = 20;           // 正确
      ptr = &b;            // 错误
      
    • 值和指针均不可变

      const int* const ptr = &a; // 值和指针都不可更改
      *ptr = 20;                // 错误
      ptr = &b;                 // 错误
      
  3. 函数参数中的 const

    • 传值参数: 如果函数参数是按值传递,const 修饰没有意义,因为传入的值本身就是副本,修改不会影响原始变量。

    • 传引用参数: 使用 const 修饰引用,可以保护原始数据:

      void print(const std::string& str) {
          // str 是只读的
          std::cout << str << std::endl;
      }
      

      好处:

      • 避免拷贝,提高性能。
      • 防止函数内部修改传入的数据。
  4. 成员函数中的 const: 当一个成员函数后面添加 const 修饰符时,表示该函数不会修改对象的任何成员变量

    class MyClass {
    private:
        int value;
    public:
        int getValue() const {
            return value; // 只读操作
        }
    };
    

    如果尝试在 const 成员函数中修改任何非 mutable 的成员变量,编译会报错。

  5. const 和数组: 声明只读的数组:

    const int arr[] = {1, 2, 3}; // 数组的内容是只读的
    arr[0] = 10;                 // 错误
    

mutable

mutable为可变的,易变的跟C++中的const是反义词。被mutable修饰的变量(mutable智能用于修饰类的非静态数据成员),将永远处于可变的状态, 即使在一个const函数中

mutable 的用法示例

  1. 普通类的 mutable 成员
#include <iostream>
#include <string>

class Logger {
private:
    mutable int logCount;  // 用于统计日志记录次数,可变
public:
    Logger() : logCount(0) {}
    
    void logMessage(const std::string& message) const {
        ++logCount;  // 即使在 const 函数中,也允许修改
        std::cout << "Log: " << message << " (Log #" << logCount << ")\n";
    }
};

int main() {
    const Logger logger;  // 声明一个 const对象
    logger.logMessage("Program started");  // 依然可以修改logCount
    logger.logMessage("Processing data");
    return 0;
}

输出

Log: Program started (Log #1)
Log: Processing data (Log #2)

在上面的例子中:

  • 类的 logCount 成员变量是用 mutable 修饰的。
  • 即使 Logger 对象是 constlogCount 仍然可以在 logMessage 函数中被修改。
  1. const 对象中的 mutable 使用
#include <iostream>

class MyClass {
private:
    mutable int counter;  // 可变成员
public:
    MyClass() : counter(0) {}

    void increment() const {
        ++counter;  // 修改可变成员
    }

    int getCounter() const {
        return counter;
    }
};

int main() {
    const MyClass obj;  // 声明 const 对象
    obj.increment();    // 修改 mutable 成员
    obj.increment();
    std::cout << "Counter: " << obj.getCounter() << std::endl;
    return 0;
}

输出

Counter: 2

使用 mutable 时应明确需求,通常用于辅助性的、不影响对象逻辑状态的数据成员。例如:

  • 缓存计算值。
  • 日志或调试计数器。

const_cast 的对比

  • mutable 是在类设计阶段明确指定的“可变性”。
  • const_cast 是临时移除 const 限制,常用于特殊需求。

typedef

用途: 1、为名称复杂的变量创建别名; 2、创建与平台无关的变量,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。 另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。 比如:size_t的介绍

// 在vs中,short 2个字节,int 4个,long也是4个,long long 8个
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
// 在Linux下,short 2个,int 4 个,long 8个,long long 也是8个
typedef short int16_t;
typedef int int32_t;
typedef long int64_t;

所以在程序源码中,只使用这些在头文件中声明的别名。 参考:typedef用法详解

总结与建议

  • 内存管理:明确堆和栈的用途,动态内存需及时释放,避免内存泄漏。
  • 关键字使用
    • static 管理变量作用域和生命周期。
    • 优先使用 inlineconstexpr 替代宏定义。
    • const 提升代码的安全性和优化性能。
    • 谨慎使用 mutable,仅在必要时放宽 const 限制。
    • typedef 或现代 using 提高类型定义的灵活性。

Blog:C++内存布局以及常用关键字

村上春树说:“跑步时我什么都不想,只是奔跑。跑步时我只感受跑步本身。”

编程时亦如此,专注写好每段代码,感受语言的精妙与力量(怎么有语文结尾升华主题那味儿了,笑死ψ(`∇´)ψ,哈哈)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2255492.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

插入排序⁻⁻⁻⁻直接插入排序希尔排序

引言 所谓的排序&#xff0c;就是使一串记录按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 常见的排序算法有&#xff1a; 今天我们主要学习插入排序的直接插入排序和希尔排序。 直接插入排序 什么是直接插入排序&#xff1f; 直接插入排序其…

Python实现中国象棋

探索中国象棋 Python 代码实现&#xff1a;从规则逻辑到游戏呈现 中国象棋&#xff0c;这款源远流长的棋类游戏&#xff0c;承载着深厚的文化底蕴与策略智慧。如今&#xff0c;借助 Python 与 Pygame 库&#xff0c;我们能够在数字世界中复刻其魅力&#xff0c;深入探究代码背后…

2024年12月6日Github流行趋势

项目名称&#xff1a;lobe-chat 项目维护者&#xff1a;arvinxx, semantic-release-bot, canisminor1990, lobehubbot, renovate项目介绍&#xff1a;一个开源的现代化设计的人工智能聊天框架。支持多AI供应商&#xff08;OpenAI / Claude 3 / Gemini / Ollama / Qwen / DeepSe…

FastAPI 响应状态码:管理和自定义 HTTP Status Code

FastAPI 响应状态码&#xff1a;管理和自定义 HTTP Status Code 本文介绍了如何在 FastAPI 中声明、使用和修改 HTTP 状态码&#xff0c;涵盖了常见的 HTTP 状态码分类&#xff0c;如信息响应&#xff08;1xx&#xff09;、成功状态&#xff08;2xx&#xff09;、客户端错误&a…

AWS 机器学习,推动 AI 技术的健康发展

目录 一、AI 正在改变生产方式二、从炒作走向务实1、选对场景2、重视数据3、产品思维4、持续优化 三、人才是最稀缺的资源四、负责任的 AI 开发五、未来已来六、启示与思考七、结语 如果说传统软件开发是手工作坊&#xff0c;那么 AI 就像工业革命带来的机器生产。 在最新的一…

OceanBase 的探索与实践

作者&#xff1a;来自 vivo 互联网数据库团队- Xu Shaohui 本文总结了目前我们遇到的痛点问题并通过 OceanBase 的技术方案解决了这些痛点问题&#xff0c;完整的描述了 OceanBase 的实施落地&#xff0c;通过迁移到 OceanBase 实践案例中遇到的问题与解决方案让大家能更好的了…

Nginx安装和配置详解

1.Nginx的安装 1.1运行以下脚本安装 yum install yum-utils -y rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm# 查看所有可安装nginx版本 yum --showduplicates list available nginx yum install nginx-1.24.0 -y …

up主亲测,ToDesk/青椒云/顺网云这三款云电脑玩转AIGC场景

文章目录 1. 前言2. 云电脑性能分析3. 基础硬件数据3.1 硬件配置3.2 AI 评测跑分 4. 云电脑 AIGC 上手实测4.1 ToDesk4.1.1 AIGC 技术集成情况4.1.2 界面及功能4.1.3 项目部署4.1.4 黑神话悟空 AI 换脸4.1.6 AIGC 文生图体验 4.2 青椒云4.2.1 AIGC 技术集成情况4.2.2 界面及功能…

ARM架构-Cache的底层原理

在主存与处理器之间加入一个小容量的存储器保存 CPU 最近一段时间内的历史访问数据&#xff0c;将在 CPU 发起访问的时候优先提供数据快速访问&#xff0c;这个介于 CPU 与主存储器之间的小容量高速存储空间我们称之为 Cache&#xff0c;即高速缓存。Cache 作为处理器与主存之间…

Codeforces Round 991 (Div. 3) F. Maximum modulo equality(区间gcd模板)

思路&#xff1a;我们由题意可以知道我们只需要维护区间gcd即可&#xff0c;因为差分一下后&#xff0c;维护的差分数组的区间gcd即为原数组所要求的值 线段树维护 #include<bits/stdc.h>using namespace std;typedef long long ll; typedef pair<ll, ll>PII; co…

树与图深度优先遍历——acwing

题目一&#xff1a;树的重心 846. 树的重心 - AcWing题库 分析 采用暴力枚举&#xff0c;试探每个点&#xff0c;除去之后&#xff0c;连通分量最大值是多少&#xff0c; 各个点的最大值找最小的 因为可以通过 dfs 来得到 根u以下点数&#xff0c;以及可以求各分树的点数&am…

消息中间件-Kafka3-kafkaJavaClient小例

消息中间件-Kafka3-kafkaJavaClient小例 Kafak Java Client private static final String KAFKA_TOPIC "kafak-test";private static String bootstrapServers "localhost:9092";private static AdminClient client null;static {Properties config n…

团队管理中如何做好目标管理

团队管理中的目标管理是确保团队高效运行的核心要素之一。 在目标管理中&#xff0c;清晰的目标设定、合理的资源分配、实时的跟踪与反馈机制是成功的关键。首先&#xff0c;设定SMART目标&#xff08;具体、可衡量、可达成、相关性强、时间限定&#xff09;能够有效聚焦团队的…

【QT】一个简单的串口通信小工具(QSerialPort实现)

目录 0.简介 1.展示结果 1&#xff09;UI界面&#xff1a; 2&#xff09;SSCOM&#xff08;模拟下位机收发&#xff09;&#xff1a; 3&#xff09;VSPD虚拟串口驱动&#xff08;连接上位机和下位机的串口&#xff09;&#xff1a; 4&#xff09;实际收发消息效果及视频演…

灵途科技亮相2024世界传感器大会 分享光纤光源技术突破

12月1日至2日&#xff0c;2024世界传感器大会&#xff08;WSS&#xff09;在郑州国际会展中心隆重举办&#xff0c;泛自动驾驶领域光电感知专家灵途科技受邀参加“光纤传感器与激光雷达”分论坛&#xff0c;并在大会上带来《激光雷达用一体化光纤光源》专题演讲&#xff0c;同与…

12月第1周AI资讯

阅读时间:3-4min 更新时间:2024.12.2-2024.12.6 目录 OpenAI CEO Sam Altman 预告“12天OpenAI”系列活动 腾讯HunyuanVideo:130亿参数的开源视频生成模型 李飞飞的World Labs发布空间智能技术预览版 中科院联手腾讯打造“AI带货王”AnchorCrafter OpenAI CEO Sam Alt…

CentOS7.X 安装RustDesk自建服务器实现远程桌面控制

参照文章CentOS安装RustDesk自建服务器中间总有几个位置出错&#xff0c;经实践做个记录防止遗忘 一 环境&工具准备 1.1 阿里云轻量服务器、Centos7系统、目前最高1.1.11版本rustdesk-server-linux-amd64.zip 1.2 阿里云轻量服务器–安全组–开放端口&#xff1a;TCP(21…

图形开发基础之在WinForms中使用OpenTK.GLControl进行图形绘制

前言 GLControl 是 OpenTK 库中一个重要的控件&#xff0c;专门用于在 Windows Forms 应用程序中集成 OpenGL 图形渲染。通过 GLControl&#xff0c;可以轻松地将 OpenGL 的高性能图形绘制功能嵌入到传统的桌面应用程序中。 1. GLControl 的核心功能 OpenGL 渲染上下文&…

指标加权评价方法

文章目录 层次分析法&#xff08;Analytic Hierarchy Process, AHP&#xff09;熵权法原理计算方法 Technique for Order Preference by Similarity to Ideal Solution(TOPSIS, 优劣解距离法)原理计算方法 层次分析法&#xff08;Analytic Hierarchy Process, AHP&#xff09; …

git管理Unity项目的正确方式

git管理Unity项目的正确打开方式 前言&#xff1a;对于刚开始git进行unity项目管理的时候&#xff0c;我采取的方式是全部文件上传&#xff0c;文件数量太多以及上传太大&#xff0c;我尝试过一下几个方法&#xff1a; 利用git的LFS大文件进行传方式&#xff0c;可行但比较麻…