自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

一个小菜鸡的学习之路

https://gitee.com/chuzhongqaq

  • 博客(124)
  • 收藏
  • 关注

原创 设计模式之创建型模式

创建型模式:创建对象的机制,从所需要实例化的对象中解耦。主要分成了五种设计模式,即工厂方法、抽象工厂、生成器、原型、单例。

2024-04-04 23:00:14 1110

原创 Qt实现画笔、擦除、保存功能

使用Qt的QPainter类,我们很容易就可以实现一个类似于画笔的功能,再重载QPaintEvent函数我们就可以使用这个画笔绘制图形到界面上。

2024-04-01 16:12:10 621

原创 Qt实现无边框圆角窗口

这时候我们可以看到圆角是没有生效的(这是在windows11下,windows10下是有圆角的,但是还是有背景色)。解决方法:我们可以使用另外一个widget覆盖在QDialog窗口上,但是这个widget也需要设置圆角和背景色。我们在使用QDialog的时候许多场景下都不需要默认的标题栏,这时候我们需要设置他的标志位。由于现代的窗口风格,我们一般会设置窗口为圆角边框的样式,我们可以使用qss的方式来进行设置。但是这时候我们的窗口都不见了,因为背景色是透明色。这时候我们可以将背景色设置为透明的。

2024-04-01 15:33:08 293

原创 Qt之QLabel介绍

QLabel是QT界面中的标签类,它从QFrame下继承,QLabel 类代表标签,它是一个用于显示文本或图像的窗口部件。我们主要介绍一下QLabel的一些简单的使用。

2024-01-30 22:51:57 615

原创 条款32:确定你的public继承塑模出 is-a 关系

如果你编写类D(“派生类”)public继承类B(“基类”),就是在告诉C++编译器(以及代码的读者)每个类型D的对象都是类型B的对象,但反之则不然。public继承意味着“is-a”。适用于基类的所有内容也必须适用于派生类,因为每个派生类对象都是基类对象。public继承和is-a的等价关系听起来很简单,但有时你的直觉可能会误导你。类Square应该public继承类Rectangle吗?

2024-01-30 21:50:13 198

原创 cmake-find_package链接第三方库

之前我们是使用了绝对路径来链接OpenCV第三方库,但是现在很多库一般会自己写一些cmake文件提供给用户,用户可以直接使用其中的内置变量即可。使用的命令就是find_package。

2024-01-28 11:40:52 853

原创 条款31:将文件间的编译依存关系降至最低

C++在分离接口和实现方面做得不好。类定义不仅指定了类接口,还指定了相当多的实现细节。如果这些头文件发生了任何变化,或者它们依赖的任何头文件发生了变化,则必须重新编译所有包含Person类的文件。

2024-01-28 11:00:55 326

原创 cmake设置Debug版本和Release版本的输出路径

项目背景:指定可执行文件和动态库输出路径都在bin目录文件夹下,由于项目中存在osg插件,然后我在项目中需要重写osg的插件,这时候就会遇到指定输出路径的问题,由于需要输出到osgPlugins-3.6.5文件夹下,所以使用默认的输出方式不行。设置输出路径的属性。

2024-01-27 23:34:44 561

原创 Qt使用中文字符串乱码的问题

我们在使用qt的时候有时候会遇到打印中文字符串的时候出现中文乱码的问题,主要是由于Qt的QString字符串存储的方式是使用utf-8的编码方式,如果我们本地的文件是使用GBK方式的编码再使用中文字符串的话就会出现打印乱码的情况。

2024-01-27 17:28:25 863

原创 条款30:透彻了解 inlining 的里里外外

内联函数背后的思想是用它的代码体替换对该函数的每次调用,大多数是编译时的行为。这可能会增加目标代码的大小(如果函数特表小还可能减少目标代码的大小)。它看上去,用起来都是函数,还避免了起函数调用的开销。如果函数过于复杂,编译器会拒绝内联请求(例如,那些包含循环或递归的函数);由于编译时无法确定,所有的虚函数都不允许内联。构造基类部分、构造成员、如果在构造对象的过程中抛出异常,对象中任何已经完全构造好的部分都会自动被销毁。内联是对编译器的请求,而不是命令。构造函数和析构函数通常不适合内联。

2024-01-27 15:47:45 229

原创 条款29:为“异常安全”而努力是值得的

如果Image构造函数抛出异常,输入流的read标记可能被移动了,而这种移动对程序的其他部分来说是可见的状态变化。在changeBackground解决这个问题之前,它只能提供异常安全性的基本承诺。下面的代码改变了bgImage的类型,使用智能指针不但可以防止资源泄漏,还提供了异常安全性;2、强烈保证:如果抛出异常,程序的状态不会改变(要么全部成功,要么就像没发生过)。从异常安全性的角度来看,这个函数很糟糕。异常安全性有两个要求,这里都不满足。1、基本承诺:如果抛出异常,程序中的所有内容都保持有效状态。

2024-01-21 21:53:17 331 1

原创 条款28:避免返回 handles 指向对象的内部成分

即便如此,upperLeft和lowerRight仍然会返回对象内部的句柄,这在其他方面可能会造成问题。特别是,它可能导致悬空(dangling )句柄:指向不再存在的对象的句柄。避免返回指向对象内部的句柄(引用、指针或迭代器)。遵守这个原则将会增加了封装性,帮助const成员函数保持const行为,并可以尽量避免发生悬空句柄的创建。这个设计可以编译,但它是错误的。我们设计的类返回的是一个const修饰的对象,但是我们还是可以修改内部对象的值。

2024-01-21 16:49:38 352

原创 cmake-动态库和静态库及使用OpenCV第三方库

项目中会有单个源文件构建的多个可执行文件的可能。项目中有多个源文件,通常分布在不同子目录中。这种实践有助于项目的源代码结构,而且支持模块化、代码重用和关注点分离。同时,这种分离可以简化并加速项目的重新编译。

2024-01-21 16:30:01 1835

原创 条款27:尽量少做转型动作

前面的方法不允许将指向多种派生类的指针存储在同一个容器中。这样的C++生成的代码既大又慢,而且很脆弱,因为每次Window类层次结构发生变化时,都必须检查所有这些代码以确定是否需要更新。旧式强制转换仍然是合法的,但新风格更可取;在C++中,强制转换是一种需要高度重视的功能。首先回顾一下强制转换的语法,相同的强制转换通常有三种不同的方式。dynamic_cast的开销较大,深层的层次结构或使用多重继承的层次结构更加昂贵。有时,两个指针的值并不相同,需要使用偏移量,在运行时应用于Derived。

2024-01-16 22:36:32 459

原创 条款26:尽可能延后变量定义式出现的时间

尽可能推迟变量定义。它增加了程序的清晰度,提高了程序的效率。未使用的变量是有开销的,所以你应该尽可能避免使用它们。开销:1个构造函数+ 1个析构函数+ n个赋值。开销:n个构造函数+ n个析构函数。

2024-01-16 22:17:22 384

原创 条款25:考虑写出一个不抛异常的swap函数

C++11之前,std::swap是通过标准的交换算法完成的(C++ 11之后用的是std::move,并明确申明为noexcept)。一般来说,重载函数模板是可以的,但std是一个特殊的命名空间。这样的行为是未定义的,虽然大多数情况下可以正常编译。C++允许类模板的偏特化,但不允许函数模板的偏特化。要交换两个Widget对象的值,真正需要做的就是交换它们的pImpl指针,但默认的交换算法无法知道这一点。它试图访问a和b中的pImpl指针,它们是私有的,所以无法通过编译!

2024-01-15 22:06:44 503

原创 条款24:若所有参数皆需类型转换,请为此采用非成员函数

乘法应该是可交换的,但是由于参数的隐式类型转换只发生在参数列表中,所以2 * oneHalf会报错,由于2是int类型的参数。重载函数修改为非成员函数,编译器还会寻找非成员运算符。这时候我们可以将operator。

2024-01-15 21:51:22 358

原创 cmake-将源文件编译为可执行文件

我们创建一个CMakeLists.txt的文件,文件的名称区分大小写,必须命名为CMakeLists.txt,CMake才能够解析。这时候cmake会认为进入了子文件夹中,所以这时候我们来看一下子文件夹中的CMakeLists.txt文件的编写。这个过程类似于厨师炒菜,需要原材料指定给他,他就可以根据这些原材料做出你想要的菜。总而言之,编写cmake最核心的内容就是让厨师可以找到所有的原材料来进行炒菜。首先看一下我们的目录结构,在外层有一个CMakeLists.txt文件。第三行,添加包含的子文件夹。

2024-01-13 17:21:20 670

原创 条款23:宁以 non-member、non-friend 替换 member 函数

优先选择非成员非友元函数而不是成员函数。这样做可以提高封装性、打包灵活性和功能可扩展性。

2024-01-13 11:04:49 341

原创 条款22:将成员变量声明为 private

更重要的是为了封装!如果你通过函数实现了对数据成员的访问,那么以后可以替换,使用者并不会察觉。将数据成员隐藏在函数接口之后可以提供各种实现灵活性。如何实现averageSoFar函数?

2024-01-10 22:19:10 331

原创 条款21:必须返回对象时,别妄想返回其引用

绝不要返回指针或引用指向一个local stack对象,或返回引用指向一个heap-allocated对象,或返回指针或对象指向一个local static对象而有可能同时需要多个这样的对象。也许你会想到一个基于operator*的实现,它返回一个定义在函数内部的静态Rational对象的引用。这里还是发生了构造和析构,更糟糕的是引用的对象被析构了。结果也是错误的,由于操作的都是同一块内存,所以执行后的结果都是最后一次执行的结果。让我们考虑在堆上构造一个对象并返回它的引用的可能性。

2024-01-10 22:12:35 534

原创 条款20:宁以常量引用传递替换值传递

通过引用传递参数也可以避免切割问题(slicing problem)。当继承类对象作为基类对象(按值)传递时,基类的拷贝构造函数会被调用,而那些派生类对象特有的部分会被“切掉”。调用了Student拷贝构造函数来初始化形参s。当validateStudent返回时,形参s被销毁。值传递的开销可能比较大。// 调用,被切割,而且没有多态。

2024-01-08 22:48:24 440

原创 条款19:设计class犹如设计type

【代码】条款19:设计class犹如设计type。

2024-01-08 22:36:24 328

原创 条款18:让接口容易被正确使用,不易被误用

shared_ptr可以解决“跨DLL问题”。当在一个DLL中使用new创建对象,但在另一个DLL中delete时,会出现此问题。shared_ptr避免了这个问题,因为它的默认删除器来自创建shared_ptr的同一个DLL中。只有12个有效的月份值,Month类型应该反映这一点。一种方法是使用枚举来表示月份,但枚举的类型安全性不高。例如,枚举可以像int一样使用(参见条款2)。这会导致至少两种类型的客户错误:没有删除指针,以及多次删除同一个指针。

2024-01-07 17:05:19 576

原创 条款17:以独立语句将 new出来的对象置入智能指针

在独立语句中将新对象存储在智能指针中。如果不这样做,在抛出异常时可能会导致微妙的资源泄漏。

2024-01-03 22:25:00 376

原创 条款16:成对使用 new 和 delete 时要采用相同形式

对于喜欢使用宏typedef的人来说,这条规则也值得注意,因为它意味着当使用new来生成typedef类型的对象时,必须说明应该使用哪种形式的delete。内存数组通常包括数组的大小,delete可以知道需要调用多少个析构函数。下面程序的行为是未定义的。至少,stringArray指向的100个string对象中有99个不太可能被正确地析构。使用delete时使用了方括号,delete假定指向的是一个数组。为了避免这种混淆,请避免对数组类型使用typedef,可以使用vector替代。

2024-01-03 22:11:17 411

原创 条款15:在资源管理类中提供对原始资源的访问

经常有API需要访问原始资源,因此每个RAII类都应该提供方法来获取它管理的资源。访问可以通过显式转换或隐式转换。一般来说,显式转换更安全,而隐式转换对客户端来说更方便。

2024-01-02 22:14:38 383

原创 条款14:在资源管理类中小心拷贝行为

3.复制底部资源:有时可以有任意多个资源的副本,需要资源管理类的唯一原因是确保每个副本都能被正确释放。在这种情况下,复制资源管理对象也应该复制它包裹的资源。2、引用计数底层资源:保留资源,直到使用它的最后一个对象被销毁。std::shared_ptr会调用delete,而我们的Lock类,需要的是解锁。4.转移底部资源的所有权:在极少数情况下,需要确保只有一个RAII对象管理资源,当复制RAII对象时,需要转移资源的所有权。1、禁止复制:如果允许复制RAII对象没有意义,这时应该禁止它。

2024-01-01 21:16:22 452

原创 条款13:以对象管理资源

为了防止资源泄漏,使用RAII对象,它们在构造函数中获取资源,并在析构函数中释放资源。两个常用的RAII类是shared_ptr和unique_ptr。shared_ptr通常是更好的选择,因为它在复制时的行为很直观。

2023-12-31 20:09:25 352

原创 条款 12:拷贝对象的所有部分

编译器生成的拷贝函数(拷贝构造函数,拷贝赋值运算符),会拷贝对象的所有数据,当你声明自己的拷贝函数时,就是在告诉编译器,默认实现中有你不喜欢的地方。如果两个拷贝函数有很多重复代码,可以先构造一个,再用另一个调用它吗?构造函数会初始化新对象,但赋值运算符只适用于已经初始化的对象。在调用赋值的时候data数据由于没有进行赋值拷贝,所以在子类的赋值中缺失了该数据。如果没有调用的话进行赋值的时候就会导致基类部分的数据没有赋值过去。出现这个问题的最狡猾的方式之一是通过继承。拷贝时,后期添加的成员被遗忘了。

2023-12-30 21:57:11 360

原创 条款 11:在 operator= 中处理“自我赋值“

当对象被赋值给自身时,确保operator=表现良好。技术途径包括:比较源对象和目标对象的地址、仔细的语句排序、copy-and-swap。确保在两个或多个对象相同(是同一个对象)的情况下,函数的行为仍然正确。

2023-12-24 23:21:58 332

原创 条款 10:令 operator= 返回一个指向 *this 的引用

实现这种操作的方式是,赋值操作返回一个指向左侧参数的引用。

2023-12-24 18:00:55 385

原创 条款 9:绝不在构造和析构过程中调用虚函数

解决这个问题有很多方法。一种是将logTransaction转换为非虚函数,然后要求派生类构造函数将必要的日志信息传递给基类构造函数。检测虚函数在构造或析构期间的调用并不总是那么容易。假设有个类的继承体系,用于建模股票交易,例如买入订单、卖出订单等。此类交易是可审计的,因此每次创建交易对象时,都需要在审计日志中创建适当的条目。

2023-12-24 17:44:20 377

原创 条款 8:别让异常逃离析构函数

析构函数永远不应该吐出(emit)异常。如果在析构函数中调用的函数可能抛出异常,则析构函数应该捕获任何异常,然后将其吞下或终止程序。如果类客户需要能够对操作期间抛出的异常做出反应,则类应该提供执行该操作的普通(即非析构函数)函数。

2023-12-23 22:31:24 375

原创 条款7:为多态基类声明虚析构函数

多态基类应该声明虚析构函数。如果一个类有虚函数,它应该有一个虚析构函数。非基类或非多态使用的类不应该声明虚析构函数。

2023-12-23 17:40:52 360

原创 条款6:若不想使用编译器自动生成的函数,就该明确拒绝

有些场景我们不需要编译器默认实现的构造函数,拷贝构造函数,赋值函数,这时候我们应该明确的告诉编译器,我们不需要,一个可行的方法是将拷贝构造函数和赋值函数声明为private。我们可以使用上面的类定义,编译器将阻止客户端拷贝HomeForSale对象的尝试,如果无意中试图在成员函数或友元函数中这样做,链接器将会报错。要禁用编译器自动提供的功能,请将相应的成员函数声明为private并且不提供任何实现。在c++11的标准中我们可以使用delete来删除函数,这样在编译的时候就会提示错误。

2023-12-20 22:56:05 355

原创 条款5:了解c++默默编写并调用了哪些函数

如果你不自己声明,编译器会替你声明(编译器版本的)拷贝构造函数、拷贝赋值运算符和析构函数。此外,如果你没有声明任何构造函数,编译器会为你声明一个默认构造函数。如果我们的类中存在以下情况:存在引用或者常量的情况,编译器可能拒绝为你的类生成相应的代码。我们可以看到报错了,这时候我们需要自己实现。

2023-12-17 23:03:50 1594 1

原创 条款4:确保对象在使用之前被初始化

手动初始化内置类型的对象,因为C++不确保会初始化它们。在构造函数中,优先使用成员初始化列表,而不是在构造函数体内赋值。以类中声明的顺序在初始化列表中列出数据成员。通过将非局部静态对象替换为局部静态对象,避免跨编译单元的初始化顺序问题。

2023-12-17 16:33:24 911

原创 条款3:尽量使用const

声明const可以借助编译器检测使用错误。const可以应用于任何作用域的对象、函数参数和返回类型,以及作为一个整体的成员函数。编译器强制执行位常量,但你应该使用逻辑常量进行编程。当const和非const成员函数具有本质上相同的实现时,可以通过让非const版本调用const版本来避免代码重复。

2023-12-16 23:14:25 385

原创 条款2:不要滥用宏

考虑到const、枚举和内联的可用性,对预处理器(特别是#define)的需求减少了,但并没有完全消除。#include仍然是必不可少的,#ifdef/#ifndef在控制编译方面继续发挥重要作用。对于简单常量,首选const对象或枚举,而不是#define。对于类似函数的宏,优先选择内联函数。

2023-12-03 16:13:04 830

windows下基于Qt实现的扫雷游戏

windows下基于Qt实现的扫雷游戏

2023-06-17

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除