
C++语言
C++学习过程中所遇到的一些问题整理
好吃还得是柚子
首先,少年,答应了别人的事就一定要做到
展开
-
编写项目的过程中使用do{ } while(0)的好处
在阅读项目源码的过程中,发现原发大量使用do{} while (0)觉得挺奇怪,不知道为什么这么写,网上找了一下发现原因有如下使用do{ } while(0)的好处1.替代{},实现局部作用域.在一些C的实现里也可以用2.避免使用goto语句,用break做跳出当你执行一段代码到一半,想跳过剩下的一半的时候,如果你正处于do while循环中,则能用break达到这个目的。如下伪代码:do{ 我执行 我执行。。 我再执行。。。 if (有什么条件满足了我) { 呀,我转载 2021-03-28 13:49:24 · 189 阅读 · 0 评论 -
构造函数为什么不能是虚函数?
从存储空间角度虚函数对应一个vtable,这大家都知道,可是这个vtable其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,无法找到vtable,所以构造函数不能是虚函数。从使用角度虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀。所以构造函数没有必要是虚函数。从实现上看vbtl在构造函数调用后才建立,因而构造函数不可能成为..转载 2021-03-20 20:49:01 · 413 阅读 · 0 评论 -
C++之override关键字
概念在成员函数声明或定义中, override 确保该函数为虚函数并覆写来自基类的虚函数。使用位置在函数调用运算符之后,函数体或纯虚函数标识 “= 0” 之前。不使用override关键字的效果#include <iostream>using namespace std;class Base{public: virtual void foo() { cout << "Base::foo" << endl; } virtual void go原创 2021-03-17 08:45:19 · 793 阅读 · 1 评论 -
sizeof 运算所得的值是在编译时还是运行时确定?
《C语言程序设计》中对sizeof的描述:C语言提供了一个编译时(compile-time) 一元运算符 sizeof,它可以用来计算任一对象的长度。 表达式sizeof 对象以及sizeof(类型名)将返回一个整型值,它等于指定对象或类型占用的存储空间字节数。依据上述描述,可以得出结论sizeof的值是在编译时确定的,而非运行期确定。如一下举例代码:// 需在C99标准的编译器下编译, ANSI C (即C89)下编译不通过#include <stdio.h>#include <原创 2021-03-13 21:16:03 · 5180 阅读 · 2 评论 -
for(;;)与while(true)的区别
死循环的有两种写法for(; ;);while(true); // while(1)两者有何区别,为何在源码中多以for(; ;)形式居多?对两条语句分别进行编译结果如下:// 编译前while(1);//编译后mov eax, 1test eax, eaxje foo+23hjmp foo+18h// 编译前for(; ;);// 编译后jmp foo+23h通过对两者分别编译后对比,for(; ;)语句不仅指令少、不占用寄存器,还没有跳转判断指令,比while(1)原创 2021-02-10 10:02:47 · 365 阅读 · 0 评论 -
C++源文件从文本到可执行文件经历的过程
对于C++源文件,从文本到可执行文件般需要四个过程预处理阶段:对源代码文件中文件包含关系(头文件)、预编译语句(宏定义)进行分析和替换,生成预编译文件。编译阶段:将经过预处理后的预编译文件转换成特定汇编代码,生成汇编文件汇编阶段:将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件链接阶段:将多个目标文件及所需要的库连接成最终的可执行目标文件...原创 2021-02-07 22:35:36 · 227 阅读 · 0 评论 -
C++左值引用与右值引用概念
右值引用是C++11中引入的新特性,它实现了转移语义和精确传递。它的主要目的有两个方面:1、消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。2、能够更简洁明确地定义泛型函数左值和右值的概念左值:能对表达式取地址、或具名对象变量。一般指表达式结束后依然存在的持久对象。右值:不能对表达式取地址,或匿名对象。一般指表达式结束就不再存在的临时对象。右值引用和左值引用的区别:1.左值可以寻址,而右值不可以。2.左值可以被赋值,右值不可以被赋值,可以用来给左值赋值。3.左值可变右值不.原创 2021-02-07 22:30:05 · 116 阅读 · 0 评论 -
C++知识点 | 虚函数与多态的实现
虚函数的实现:在有虚函数的类中,类的最开始部分是一个虚函数表的指针,这个指针指向一个虚函数表,表中放了虚函数的地址,实际的虚函数在代码段(.text)中。当子类继承了父类的时候也会继承其虚函数表,当子类重写父类中虚函数时候,会将其继承到的虚函数表中的地址替换为重新写的函数地址。使用了虚函数,会增加访问内存开销,降低效率。多态的实现:多态的实现主要分为静态多态和动态多态,静态多态主要是重载,在编译的时候就已经确定;动态多态是用虚函数机制实现的,在运行期间动态绑定。举个例子:一个父类类型的指针指向一个子.原创 2021-02-05 08:11:32 · 308 阅读 · 0 评论 -
C++知识点 | 静态函数与虚函数、重载与重写的区别
静态函数和虚函数的区别静态函数在编译的时候就已经确定运行时机,虚函数在运行的时候动态绑定。虚函数因为用了虚函数表机制,调用的时候会增加一次内存开销重载与重写的区别重载:两个函数名相同,但是参数列表不同(个数,类型),返回值类型没有要求,在同一作用域中重写:子类继承了父类,父类中的函数是虚函数,在子类中重新定义了这个虚函数,这种情况是重写...原创 2021-02-05 08:05:19 · 497 阅读 · 0 评论 -
C++经典面试题 | 析构函数与虚函数
为什么析构函数必须是虚函数?为什么C++默认的析构函数不是虚函数?参考回答:将可能会被继承的父类的析构函数设置为虚函数,可以保证当我们new一个子类,然后使用父类指针或引用指向该子类对象,释放父类指针时可以释放掉子类的空间,防止内存泄漏。C++默认的析构函数不是虚函数是因为虚函数需要额外的虚函数表和虚表指针,占用额外的内存。而对于不会被继承的类来说,其析构函数如果是虚函数,就会浪费内存。因此C++默认的析构函数不是虚函数,而是只有当需要当作父类时,设置为虚函数。...原创 2021-02-05 08:00:54 · 294 阅读 · 0 评论 -
C++四种智能指针详解
四种智能指针:shared_ptr,unique_ptr,weak_ptr,auto_ptrC++里面的四个智能指针:shared_ptr,unique_ptr,weak_ptr,auto_ptr其中前三个是c++11支持,并且最后一个已经被11弃用。智能指针的使用智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。C++11中最常用的智能指针类型为 shared_ptr它采用引用计数的方法,记录当前内存资源原创 2021-02-04 08:35:08 · 1522 阅读 · 0 评论 -
C++面试经典题 | 指针和引用、指针和数组的区别
说一下指针和引用的区别指针是变量,这个变量存放的是所指内容的地址。引用是别名,与所引用变量占用同一内存空间使用 sizeof看一个指针的大小是4,而引用则是被引用对象的大指针可以被初始化为NULL,而引用必须被初始化且必须是一个已有对象的引用作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象可以有 const指针,但是没有 const引用指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能被改变指针可以有多级指针(*p),而引用只有一原创 2021-02-03 09:05:30 · 375 阅读 · 0 评论 -
C++面试经典题 | C++中四种强制类型转换
说一说C++中的四个cast转换C++中四种类型转换是:static cast, dynamic cast, const cast, reinterpret castconst cast用于将cons变量转为非 conststatic cast用于各种隐式转换,比如非cons转onst,wod转指针等 static cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知dynamic cast用于动态类型转换。只能用于含有虚函数的类,用于类层次间的向上和向下转化。只能转指针或引用。原创 2021-02-03 08:58:24 · 699 阅读 · 5 评论 -
C++面试经典题 | static关键字的作用
说一下static关键字的作用全局静态变量在全局变量前加上关键字 static,全局变量就定义成一个全局静态变量静态存储区,在整个程序运行期间一直初始化:未经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化)作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾局部静态变量在局部变量之前加上关键字 static,局部变量就成为一个局部静态变量。内存中的位置:静态存储区初始化:末经初始化的全局静态变量会被自动初始化为0(自动对象的值原创 2021-02-03 08:51:57 · 2327 阅读 · 4 评论 -
new/delete和malloc/free的区别联系
1.先来谈谈new和delete在C++中堆内存的分配和释放是通过new和delete来操作的,它们和C语言的malloc和free有什么区别呢?(1)new的底层也是通过malloc来开辟内存的new比malloc多一项功能,就是开辟完内存,还可以进行初始化操作如下:int *p = new int(10);上面是new的基本操作,10代表堆上开辟的整形内存的初始值;如果是自定义类类型的话,如下:Test *p = new Test(); // Tset是一个实现定义好的类这个语句不原创 2021-02-02 08:20:36 · 1267 阅读 · 2 评论 -
memset函数()通俗易懂解释
什么是memset()函数?memset()函数原型是 extern void* memset(void *buffer, int length, int buf)buffer 是指针或者数组,void是要初始化的首内存的首地址;length是要初始化的变为的数据,buf是buffer的长度,即大小。网络编程中memset函数多用于socket套接字编程中清空数组,如:memset(IPNumber, 0, 4) ; //将IPNumber数组中的4位置为0该函数用于将一段内存空间全部设置为某个原创 2021-01-31 10:59:10 · 3605 阅读 · 0 评论 -
RAII机制介绍
RAII机制介绍RAII全程为Resource Acquisition Is Initialization(资源获取即初始化),RAII是C++语法体系中的一种常用的合理管理资源避免出现内存泄漏的常用方法。以对象管理资源,利用的就是C++构造的对象最终会被对象的析构函数销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。使用RAII机制的原因RAII是合理管理资源避免出现内存泄漏的常用方法。那原创 2021-01-31 08:42:32 · 5313 阅读 · 0 评论 -
extern关键字用法详解
在C语言的语法体系中,关键词extern放在变量、函数的声明式前,表示变量、函数是在别处(可以是别的文件或者程序的其他位置)定义的,但是此处声明使用。1. extern修饰变量的声明。举例来说,如果文件a.c需要引用b.c中变量int v,就可以在a.c中声明extern int v,然后就可以引用变量v。能够被其他模块以extern修饰符引用到的变量通常是全局变量。还有很重要的一点是,extern int v可以放在a.c中的任何地方,比如你可以在a.c中的函数fun定义的开头处声明extern in转载 2021-01-28 07:55:17 · 1407 阅读 · 0 评论 -
C++多态性质
多态概念在C++语法体系中,多态分为静态多态和动态多态。静态多态就是重载:因为在程序编译期间(地址早绑定)即可确定,所以称静态多态,在编译时就可以确定函数的调用地址。动态多态就是重写:派生类通过继承重写父类中的虚函数实现动态多态,在程序运行(地址晚绑定)时将会根据对象的实际类型类调用相应的函数。如果对象类型是子类,就调用子类的函数;如果对象类型是父类,就调用父类的函数,(即指向父类调父类,指向子类调子类)此为多态的表现。多态的实现构成多态需要两个条件:调用函数的对象必须是父类的指针或者引用。原创 2021-01-26 16:43:08 · 623 阅读 · 0 评论