- 博客(47)
- 收藏
- 关注
原创 C++中,函数模板不匹配自定义类型的两种解决方式
以上代码能通过编译,但是运行会出错,因为编译器无法对自定义类型进行相等比较。②函数模板只有在使用时才会占用内存,不被调用时不占用空间。为什么不用直接使用普通函数呢?①使用函数模板有整体性,方便修改操作。②利用具体化的函数模板。
2025-03-19 15:13:00
165
原创 C++中,虚函数及其底层原理
但当我们以子类(张三类和李四类)去重写父类Person的虚函数时,子类会将虚函数表中的内容进行一个覆盖(或者叫替换),将自己重写的函数地址覆盖原先的函数地址,这将导致在以子类对象传给父类引用时,会使用子类的函数地址进行访问函数。因为多态分为静态多态和动态多态, 静态多态是指函数地址在编译阶段就定型了,无法改变,后续程序运行时,永远都是套用的定型的函数地址,自然只能使用这唯一一个函数。再创建两个子类继承Person类,分别为张三类和李四类,子类重写了父类Person的show成员函数,代码如下。
2025-03-02 14:37:51
261
原创 C++中,菱形继承及其解决方式(虚基类、虚继承)的底层原理
不使用虚继承时,在B类和C类中会分别有一个age成员,但是虚继承之后,B类和C类都不会有age成员,而是形成了一个。菱形继承指的是 一个基类被两个子类继承,然后又有一个孙子类继承了这两个子类,如图所示。这样D继承了两份A的数据,从而产生二义性,我们明显知道,这是资源浪费。,偏移量与D类的B类和C类基地址加之后会指向 同一个A类成员。虚基类指针vbptr(记住不是虚指针vptr)这样,就避免了菱形继承带来的资源浪费和二义性。
2025-02-26 19:45:00
196
原创 C++中,子类父类有同名成员变量成员函数如何访问?
③有同名函数时,子类将隐藏所有父类的同名函数(即隐藏包括重载的函数)②通过在调用的点后面添加作用域可以访问父类的同名成员。①通过子类对象直接访问时,是访问子类的。
2025-02-26 18:48:49
141
原创 C++中,继承中构造和析构函数的顺序
现有爸爸再有儿子,现有父类构造再有子类构造(与类对象做另一类的成员做区分),而析构依旧符合栈的先进后出原则,先创建的后析构。
2025-02-26 18:36:33
177
原创 C++中,三种继承方式区别
将父类成员继承下来后,将访问权限全部改为protected。将父类成员继承下来后,将访问权限全部改为private。不改变父类成员的访问权限,直接继承下来。无论哪种继承都无法继承父类(基类)中的私有成员。②保护继承 protected。③私有继承 private。①公有继承 public。
2025-02-26 18:03:12
58
原创 C++中,仿函数与函数调用运算符重载
先弄清楚函数调用运算符重载就行,代码示例如下。这跟普通函数调用长得一模一样,而这就叫仿函数。结果就是打印输出你好。
2025-02-26 16:15:14
170
原创 C++中,重载赋值运算符=
这时就跟深浅拷贝问题(见我另一篇文章)一样,简单的值复制可能会导致堆区的数据重复释放,发生报错,如下代码结果可知,用编译器自带的=,地址都是同一个。编译器会给一个类默认添加一个operator=的重载运算符函数,相当于是值复制。所以此时要添加一个重载赋值运算符的函数,如下所示。如果加个析构函数去释放堆区内存,就会出现错误。,且析构函数不会导致程序出错了。还是深浅拷贝那一套,换汤不换药。
2025-02-26 16:00:29
193
原创 C++中,++递增运算符重载
首先与 <<左移运算符 和 +号运算符 不同的是,++运算符是只有一个操作数的,所以不用考虑左右操作数问题,那么出现一个新问题,怎么知道是前置++还是后置++呢?因为如果要验证我说的第一个为什么的话,去除引用会报错,因为。为什么后置++返回值不能是引用,只能是值?因为要重叠++,如代码中的++(++p1)这个时候要引入一个概念,叫占位参数(可以作为函数重载条件),代码如下。首先创建一个类,然后重载<<运算符使得能直接cout该类,代码如下。区别很简单,就看有没有占位参数,有占位参数就是后置,没有就是前置。
2025-02-26 15:44:43
151
原创 C++中,左移<<运算符重载
答案是不行的,只能用全局函数,因为<<若作为成员函数,那么对象p1就一定是左操作数,但是在<<的左边必须先是cout 才行,所以必须是全局函数形式才行。此时就可以用到重载运算符关键字operator了, 但是+运算符重载可以有两种方式(成员函数、全局函数),<<运算符重载可以吗?什么是ostream?结果显然是11,这是因为编译器认识int型,知道怎么用<<去操作int型,但当遇到我们自定义类型呢?最后,记住,谁在左边就是左操作数,谁在右边就是右操作数!而cout全局只有一个,所以必须加上引用符&
2025-02-26 14:24:34
165
原创 C++中,+号运算符重载
最后,还需注意一点是,运算符+号 是有左右操作数的,而不论是成员函数也好,还是全局函数也好,左右操作数其实很好记, 编写函数时,想想以本质去调用这个函数时谁在左边就是左操作数,谁在右边就是右操作数,切记,在重载<<运算符时会很强调这一点。这是运算符重载的本质,对象p1调用其成员函数operator+(p2),最后返回值是一个Person的对象,被p4以默认拷贝构造复制,以此来达到我们想要的效果。若成员变量为私有,则可以将该全局函数设为该类的友元全局函数即可。还有另一种方法,是以全局函数形式,代码如下。
2025-02-26 14:08:35
146
原创 关于C++中指针在内存中的见解
但指针存在的同时,不代表指针有意义。比如,野指针指向未知内存空间,野指针存在但是无法访问内存。,那么不做其他操作时,创建该类时,并不会调用另一个类的构造函数。在创建类的示例对象时,若类内。指针是地址,这是毋庸置疑的。
2025-02-25 20:55:43
143
原创 C++中,const修饰成员函数与类对象,以及mutable关键字
添加const变为 void func() const { };这可以成为常成员函数,常成员函数不可以修改普通成员变量,此时mutable关键字生效了,比如。而const修饰的类对象,只能调用常函数,同时也只能修改mutable修饰的成员变量。PS:const修饰的对象仍然可以访问非mutable修饰的成员变量。
2025-02-25 18:36:22
127
原创 C++中,类对象所占内存大小以及this指针
成员函数与成员变量分开存储,类对象所占内存大小只与成员变量大小有关。C++为了区分对象,哪怕是一个空对象,也占。哪一个对象使用了成员函数,this指针就指向哪个对象。而this指针,就是。
2025-02-25 18:03:09
179
原创 C++中,静态成员及静态成员函数知识点
所以静态成员和静态成员函数都是属于类的,换句话可以说,静态成员(函数)是属于全部对象的,也可以说静态成员(函数)是所有类对象所共有的一个成员(函数)。静态成员变量: ①所有对象共享一个静态成员变量 ②静态成员变量必须类内声明,类外赋初值。静态成员函数: ①所有对象共享一个静态成员函数 ②静态成员函数只能访问静态成员变量。此时引入一个新知识点,类作用域符,如下。首先,特别注重一点就是,C++中,
2025-02-25 17:34:47
168
原创 C++中,其他类的对象作为另一个类成员时的注意点
首先我们要明白一点,类相当于一个人,而其成员和成员函数是一个人的《各个部位》和《行为》,缺了你身体的《各个部位》和《行为》,那么你这个人就不存在,即该类就不存在。所以第一个问题就迎刃而解,人在妈妈肚里先有的《各个部位》,所以类内的对象成员先进行构造函数执行,后再执行该类的构造函数。析构函数依旧符合栈的先进后出原则,故执行顺序与构造函数执行顺序相反。下面代码中结果如何呢?
2025-02-25 17:07:00
193
原创 C++中,构造函数给成员属性赋初值的另一种写法
构造函数赋值大家首先想到的肯定就是自己写的有参构造函数,像函数那样调用即可。还有一种方法平时可能不怎么用,但是见到了不能见怪,如下。这两段代码执行结果都是一致的。
2025-02-25 16:46:47
108
原创 C++中,分文件编写简单介绍
在头文件中要包括如下内容(简单记忆就是最基本的开头内容 + 函数声明,即可)分文件编写分为两种文件:①头文件 ②源码文件。在源码程序中只需要包括该头文件即可。使用时只需要在源码添加该头文件即可。
2025-02-25 16:27:22
178
原创 C++中,构造函数与析构函数执行顺序
但析构函数不一样,对象创建都是压栈保存的,所以析构函数符合栈的先进后出原则,故先创建的对象后执行析构函数。构造函数执行顺序很简单,就是先创建的对象先执行构造函数。
2025-02-25 16:22:20
82
原创 C++中,匿名对象相关知识点
原因是匿名对象创建作为单独语句时,当前行执行结束后系统会立即回收掉匿名对象,而不会像普通对象那样等到整段代码段运行结束时才结束生命周期。匿名对象无法使用拷贝构造函数来进行创建,因为编译器会自动将该语句看成一个对象的创建,从而导致二次创建重名对象的错误。匿名对象还有一个性质,先想想以下代码的结果。匿名对象指的是无对象名的对象,代码如下。匿名对象可以用来创建新对象,如。
2025-02-25 16:16:58
125
原创 深拷贝与浅拷贝
浅拷贝即值拷贝,是编译器默认拷贝构造函数,只进行值拷贝 当对象的一个指针指向堆区数据时,浅拷贝的操作只是将这个堆区数据地址复制一遍,当两个对象进行析构时,会将这个堆区数据释放两次,此时就出现二次释放堆区数据的错误了。而深拷贝就是重新开辟一个堆区内存,然后复制原对象堆区数据到该新内存中去,这样原对象和拷贝对象就不会释放同一个堆区数据了。
2025-02-24 22:11:49
186
原创 内存泄漏与虚拟头结点
首先,内存泄漏是指程序未能释放不再使用的内存,导致内存占用持续增加。这可能发生在动态分配内存后没有正确释放的情况下。比如用new分配了内存但忘记delete,或者在某些情况下循环中没有及时释放。虚拟头结点就是创建一个局部变量,以该局部变量为头结点,到程序结束时该虚拟头结点会自动释放内存,无需手动释放,避免了内存泄露的风险。
2025-02-24 14:53:48
83
原创 C++中,引用作为函数返回值时
所以引用作为函数返回值时,不应该返回局部变量的引用,因为局部变量在函数运行结束时释放了,函数体外部使用时会报错。若返回的是一个堆区变量,则函数调用可以作为左值对这个堆区变量进行操作。引用的本质是指针,不过编译器自动将代码编译了。
2025-02-24 14:08:31
199
1
原创 C++中,指针常量与常量指针
const位置看常量在前在后, 常量指针中 常量在前,则const在前,指针常量中 常量在后则const在后。指针常量 意思是 指针的常量 而指针就是地址,地址不变就是方向不变。常量指针 意思是 常量的指针 无法通过指针去修改所指向的值。
2025-02-24 13:59:38
146
转载 java对象值传递和对象传递的总结
耐心看完,一定能懂!!!特别详细前两天项目lead面试我,问的第一个问题就是值传递和对象传递的问题,这问题之前只知道皮毛,不是很清晰,今天专门总结下。 先看基本类型作为参数传递的例子:public class Test1 {public static void main(String[] args) {int n = 3;System.out.println("Before change, n = " + n);changeData(n);System.ou...
2022-03-02 23:05:39
754
空空如也
cache行长和主存块大小
2022-11-02
TA创建的收藏夹 TA关注的收藏夹
TA关注的人