分享我在编程中的设计概念和遇到的技术要点,让我们在工作和生活中共同追求自由
近年来,自由的概念给我留下了深刻的印象。不久前,我看到一个叫做辞职自由的词。
是的,我刚刚辞职。站在新的公司山前,我认为当其他人意识到财务自由时,我追求的是加班工作和加班工作中努力搬砖的自由。同时,我也有不加班的自由。该结构使我们可以自由自在。
01编写破碎的想法
我的编程概念逐渐形成于公司的砖块中,并在导师和大咖啡的影响下形成。本文中的观点是从实际的技术实践中得出的,其中一些概念也从前辈的设计结果中继承而来。如果有任何违规行为,请通知我们。我特别感谢那些给我建议的人们,站在大咖啡的肩膀上,让我们进一步了解。
本文提到的大多数编程概念都是基于C ++实现的基本技术,这些技术与Qt框架,设计模式和面向对象有关。您可能会认为现在是AI云的时代,这些都太旧了。但是我认为这些是编程的基础,这是正确的编程世界观。
02内存管理
有一天,当我调试一个错误时,我发现Qt源代码中几乎没有“ *”指针。回想起公司的代码(大多是2010年写的,满是星星),我闭上了眼睛,感觉到了熟悉的腐败味。
2019年,我接管了一个项目,该项目动荡不定,几乎要死了。在此之前,一些同事在其中苦苦挣扎了几个月。看到该版本即将发布,压力测试无法运行3个小时。
在C ++编程中,内存一直是一个重大问题。在Qt平台中,我建议使用Qt智能指针,对象树和大内存技术进行内存管理。
03智能指针
QScopedPointer
QScopedPointer p(new MyClass());
范围的意思是“范围”。可以理解,由QScopedPointer对象p管理的内存在p的生命周期内是有效的。
这是一个智能指针,经常在项目中使用,经常使用的场景:
1、类成员指针
class MyPrivateClass;
class MyClass
{
private:
QScopedPointer<MyPrivateClass> privatePtr;
public:
MyClass();
inline ~MyClass() {}
};
注意:
禁止将QScopedPointer与QObject对象树中的对象结合使用。当对象树中的父节点被释放时,其子节点将被释放。当QScopedPointer对象再次释放子内存时,将导致错误。
对象跟踪指针QPointer
QPointer标签=新的QLabel(父级);
对于QObject的跟踪指针,QPointer不会释放目标对象。目的是记录QObject,以便可以在其他成员函数中使用它。
QPointer就像一个GPS定位器。释放目标对象后,它会自动设置为0,也就是说,在分解父对象时会分解子对象QLabel,然后标签记录的内存为0。
应注意,托管目标对象必须从QObject派生。
这是一个智能指针,经常在项目中使用,经常使用的场景:
1、 QObject子对象,用作成员指针时
2、当记录指向不受自身管理的QObject对象的指针时
共享指针QSharedPointer和QWeakPointer
QSharedPointer p(new MyClass());
共享指针意味着多个QSharedPointers共享同一内存对象。释放p本身时,它将确定其他QSharedPointer引用是否共享由它自己管理的内存对象,如果没有,则释放托管的内存对象。
常用场景:
1、类的成员指针,特别是在容器类型中使用的成员指针,减少了容器内存对象的释放操作,容器的添加和删除操作,并且QSharedPointer保证释放了它管理的内存。
注意:
如果将由QSharedPointer管理的对象指针A注册到需要管理A的生命周期的其他类中,则会发生错误。
例如,如果postEvent的QEvent对象由QSharedPointer管理,则QSharedPointer将在退出范围时释放QEvent,从而导致在postEvent处理期间访问QEvent,或者在处理事件之后释放QEvent,这都是错误的
弱共享指针QWeakPointer
刚接触Qt的学生在Internet上搜索文章时可能会有点缺乏共享的知识。 QWeekPointer可以理解为与QPointer相同的跟踪指针,QPointer旨在记录和跟踪QObject对象,QWeekPointer跟踪QSharedPointer对象。
我通常很少在项目中使用弱共享指针。其目的是充当QSharedPointer帮助程序类,以减轻QSharedPointer的循环依赖。在面向对象设计中,循环依赖不是理所当然的事情。
关于智能指针的一些想法
智能指针是用于内存管理的工具。从语法上讲,它减少了C ++工程师的内存管理难度,有效地防止了由于无意的笔误导致的内存泄漏,并减少了内存管理代码的数量。但是,智能指针本质上不能解决项目中的内存管理问题。
作为C ++工程师,您必须了解内存管理机制,并清楚知道何时应该创建和销毁内存。否则,当选择使用哪个智能指针来管理目标存储器时,将无法做出正确的决定,否则项目存储器将异常。除非将来没有特定版本的Qt,否则只有一个智能指针QPointer。
为解决内存问题,我们在实际项目中更多地依赖于QObject对象树和内存池。
04对象树
Qt使用树结构描述对象之间的父子关系,如下图所示,P是树的父节点,A2是第一级子节点,B 1、 B2是第二级子节点。

对象树的内存管理。释放A2时,首先释放B 1、 B2,然后将其从P的子节点列表中删除。
Qt对象树的特性可确保在释放父对象时,将释放子对象的内存。在实际的项目中,我会经常使用它。
QObject对象树的实现很容易理解。 QObjectData记录一个指向父对象parent的指针,以及一个QList子对象列表子对象。
在UML中,QObject将自身描述为自身的组合,这并不意外。

QObject延迟发布deleteLater
在QObject对象机制中,有一个非常有用的功能deleteLater,其功能是延迟对象的破坏。
是什么意思?调用deleteLater之后,QObject对象不会立即销毁,而是在下一个消息循环中销毁。
所使用的方案(例如替换容器中的子控件)可以避免屏幕闪烁或其他需要延迟释放的地方。
05内存池
内存池
大内存通常称为内存池。实际上,内存池不仅管理大内存,还管理小内存。
在项目中,内存池用于两个目的,一个是提高性能,另一个是避免内存碎片。
性能提升
对于频繁释放小块内存的应用程序,使用内存池相对于新的内存池具有明显的性能改进,但为此目的,没有足够的理由使用内存池。
避免内存碎片
对于内存池技术,更多的需求是避免内存碎片。
我在一个项目中遇到了无法申请20M内存的情况,此时系统内存明显大于20M。为什么?由于系统内存被碎片分割,因此没有连续的20M内存。

当系统内存管理不够“智能”时,C ++程序员将强烈希望进行控制,并希望一切都掌握在自己手中,包括潜在的内存风险。
通过内存池技术,当由于碎片导致内存不连续时,我们的程序就有机会重新排列内存以满足应用程序大小。

对于内存池技术,Qt没有提供实现,但是有很多开源库引用,您可以搜索“内存池”。

本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-322407-1.html
期待期待
别找借口