const和修饰指针的几种用法

ops/2024/12/19 5:03:55/

昨天闲着没事去面试了一个C++岗位,问了很多基础的东西都没答上来。主要原因是这些知识在硬件资源丰富的pc端用的不多,二来确实很久没温习之前的C++相关的知识了。在面试官问了几次类似的问题没有答好的情况下(还喜欢问你确不确定),最后面试结果也就可想而知了。

1.const和指针

在 C++ 中,const 的作用取决于它修饰的内容(指针本身指针指向的值)。理解 const 的修饰规则可以通过以下原则:


1. 快速判断的方法

声明形式从右往左读解释指针行为值行为
const int* ptr;指针指向的值是常量,不能修改值可改变地址不可改变值
int* const ptr;指针本身是常量,不能改变指向不可改变地址可改变值
const int* const ptr;指针本身是常量,指向的值也是常量不可改变地址不可改变值
int* ptr;普通指针,可修改指针指向的地址和指针指向的值可改变地址可改变值

总结:看 const 修饰什么

  1. const 修饰 int*:表示指针指向的值是常量,不能通过指针修改值。
  2. const 修饰ptr:表示指针本身是常量,不能改变指针指向的地址。
  3. 两个 const 同时使用:表示指针和指针指向的值都不能修改。

通过从右往左读声明,可以快速理解 const 的实际作用,应用到代码中时就能明确意图。

2.Qt的资源管理

这个问题主要是Qt的parent设置问题,我也是浅浅的记得是这样管理的。后面面试官又问了我确不确定,第一我确实不确定(其实有点确定),第二就是软件工程里面不确定的东西实在是太多了,所以就说了确实不确定。

1. parent 的作用

  • Qt 的对象树以 parentchild 关系为基础。当一个对象设置了 parent
    • 子对象会被自动添加到父对象的子对象列表中。
    • 当父对象销毁时,其所有子对象会被 自动销毁
  • 如果 parentnullptr,则该对象不会被其他对象管理,需要手动管理内存

2. parent = nullptr 时的内存管理

  • 如果创建一个 QObject 或其子类对象(如 QWidget),且没有设置 parent,它不会被 Qt 的对象树自动管理。
  • 在这种情况下,你需要显式调用 delete 来释放内存,或者将其分配到栈上以自动管理生命周期。
// 在堆上创建,没有 parent
QObject *obj = new QObject();
// 需要手动删除
delete obj;// 在栈上创建,无需关心内存释放
QObject obj2;

3. 常见场景分析

(1)动态分配且 parent = nullptr
QWidget *window = new QWidget(nullptr); // 没有 parent
  • window 不会被 Qt 自动管理,因此需要在适当的时候手动 delete
  • 如果不 delete,会导致 内存泄漏
(2)分配在栈上
QWidget window; // 没有 parent
  • 对象分配在栈上,生命周期由 C++ 的作用域管理,无需手动释放。
  • 作用域结束后,对象自动销毁。
(3)结合 Qt 的智能指针

从 Qt 5.11 开始,可以使用 QScopedPointer 或标准的 std::unique_ptr 来管理内存:

#include <QScopedPointer>
QScopedPointer<QObject> obj(new QObject(nullptr)); // 自动释放内存

或者使用标准智能指针:

#include <memory>
std::unique_ptr<QObject> obj = std::make_unique<QObject>(nullptr); // 自动释放内存

4. 避免问题的建议

  1. 优先设置 parent
    如果可能,尽量为对象设置 parent,让 Qt 自动管理其生命周期。特别是 GUI 对象,通常需要将其子对象挂接到父对象上。

    QWidget *child = new QWidget(parent); // parent 销毁时,child 自动销毁
    
  2. 明确生命周期管理

    • 如果 parent = nullptr,确保在适当时候调用 delete,或使用智能指针。
    • 避免同时使用 delete 和 Qt 的 parent 管理,这可能导致二次销毁或未定义行为。
  3. 检查内存泄漏
    使用工具(如 Valgrind 或 AddressSanitizer)检查未正确释放的内存。


5. 常见误区

  • 误解 Qt 的内存管理全自动化:只有设置了 parent 的情况下,Qt 才能管理内存。parent = nullptr 时,内存管理完全是开发者的责任。
  • 对对象树的过度依赖:设置 parent 可以简化内存管理,但在复杂对象关系下,可能导致意外的销毁顺序或内存问题。

总结

QObjectparentnullptr 时:

  • 需要开发者手动管理内存(使用 delete 或智能指针)。
  • 分配在栈上的对象无需特别管理。
  • 为避免内存泄漏或未定义行为,应始终明确对象的生命周期,合理使用 parent 或智能指针。

3.教训

既然是面试,很多八股文还是要看滴,不看是会吃亏滴…


http://www.ppmy.cn/ops/143083.html

相关文章

opencv礼帽和黑帽运算

礼帽 原始输入 - 开运算结果&#xff0c;留存的以白色毛刺为主 黑帽 闭运算 - 原始输入&#xff0c;保留的更多是原始轮廓 # 导入OpenCV库&#xff0c;用于图像处理 import cv2 import numpy as np # 从matplotlib库中导入pyplot模块&#xff0c;用于绘制图像 from …

包子凑数(2017年蓝桥杯试题H)

【问题描述】 小明几乎每天早晨都会在一家包子铺吃早餐&#xff0c;他发现这家包子铺有N种蒸笼&#xff0c;其中第i种蒸笼恰好能放Ai(i为下标)个包子。每种蒸笼都有非常多个&#xff0c;可以认为是无限笼。 每当有顾客想买X个包子。卖包子的大叔就会迅速选出若干笼包子&#xf…

【C++】sophus : common.hpp 丰富的字符串格式化、日志记录和数学常量处理功能 (七)...

这段C代码实现了一个名为Sophus的库&#xff0c;提供了各种实用功能。主要内容包括&#xff1a; 宏定义和条件编译&#xff1a; 使用条件编译定义了一些宏&#xff0c;用于在不同编译器下处理函数名称等。定义了用于格式化字符串和打印日志的宏。定义了用于运行时断言的宏&…

Python爬虫获取商品销量详情

在这个数据驱动的时代&#xff0c;获取商品销量详情已经不再是简单的点击和浏览。我们需要的是速度、效率&#xff0c;还有一点点的...偷偷摸摸。没错&#xff0c;今天我们要聊的是如何使用Python爬虫来“偷窥”商品销量详情。别担心&#xff0c;我们保证一切都是合法合规的&am…

revit转gltf,revit转3dtiles,如何将Revit模型转为3DTiles格式并在Cesiumjs中高效可视化

Revit模型导出gltf、glb与3dtiles有多种方式&#xff0c;但一般的商业工具收费普遍较高&#xff1a;Cesiumlab导出3dTile格式数据&#xff0c;Cesiumlab暂时可试用3天&#xff0c;会员版收费每年800&#xff1b;BimAngleEngine导出3dTile格式数据BimAngleEngine暂时可试用30天&…

CTFHUB靶场关于SSRF保姆级攻略

一.内网访问 输入127.0.0.1/flag.php 二.伪协议读取文件 输入?urlfile:///var/www/html/flag.php 右键页面查看源代码 三.端口扫描 尝试一下index.php&#xff0c;没有显示&#xff0c;说明有这个文件 上方题中提示我们端口在8000-9000中我们用burp suite抓包&#xff0c;开启…

Mysql笔记

windows安装记录Windows中Mysql安装-CSDN博客 用到的库 通过网盘分享的文件&#xff1a;atguigudb.sql 链接: https://pan.baidu.com/s/1YfC20c2vK9odn-XRJJwUJw 提取码: utk7 --来自百度网盘超级会员v5的分享 Mysql4中表关联关系 1.1对1,比较少用,因为完全可以一张表,当有…

pytest -s执行的路径

pytest -s执行的路径&#xff1a; 直接写pytest -s&#xff0c;表示从当前路径下开始执行全部.py的文件。 执行具体指定文件&#xff1a;pytest -s .\testXdist\test_dandu.py 下面这样执行pytest -s 会报找不到文件或没权限访问&#xff0c; 必须要加上具体文件路径pytest -s…