c++基础
Erlei_n
这个作者很懒,什么都没留下…
展开
-
内联函数有什么优点?内联函数和宏定义的区别
用内联函数取代宏:1.内联函数在运行时可调试,而宏定义不可以;2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会; 3.内联函数可以访问类的成员变量,宏定义则不能; 4.在类中声明同时定义的成员函数,自动转化为内联函数。内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,在编译的时候内联函数可以直接被镶嵌到目标代码中。内联函数...转载 2019-04-25 09:39:44 · 1784 阅读 · 0 评论 -
STL实现了哪些排序算法
排序算法按照是否将元素放入到内存中,排序分为内部排序和外部排序。内部排序适合元素不多的文件,按照元素的排序原则,内部排序分为:插入排序 交换排序 选择排序 归并排序插入排序基本方法是:寻找一个指定元素在待排序元素中的位置,然后将它插入直接插入基本思想:每次将一个待排序的元素按其关键码的大小插入到一个已经排好序的有序序列中,知道全部元素排序好。void insert...转载 2019-04-30 17:00:51 · 679 阅读 · 0 评论 -
strtok函数在使用上要注意什么问题
一、函数的简介 函数原型:char *strtok(char *s, char *delim) 功能:作用于字符串s,以delim中的字符为分界符,将s切分成一个个子串;如果,s为空值NULL,则函数保存的指针SAVE_PTR在下一次调用中将作为起始位置。 返回值:分隔符匹配到的第一个子串二、主要内容1、函数的作用...转载 2019-05-08 21:43:37 · 814 阅读 · 0 评论 -
char * const p ,char const * p, char const * const p区别
const char *p; // 声明一个指向字符或字符串常量的指针(p所指向的内容不可修改)char const *p;// 同上,由于没有const *的运算,若出现const *的形式,则const实际上是修饰前面的,所以char const *p和const char *p一样。char* const p; //const修饰的是p,p不能修改。声明一个指向字符或字符串的指针...原创 2019-05-08 21:52:04 · 1498 阅读 · 0 评论 -
介绍一下右值引用和移动语义和完美转发
这篇文章介绍的了第三章中右值引用相关的内容。在介绍该内容之前,会对一些相关问题进行解释,便于理解后面的内容。 并且,提前说明,许多编译器会多拷贝构造和移动构造进行优化省略,这样就看不到拷贝构造和移动构造的过程,需要在编译器选项中设置-fno-elide-constructors来关闭优化。指针成员和拷贝构造当一个类中含有指针成员时,由于默认的拷贝构造函数只会进行浅拷贝,所以当我们写出一下代...转载 2019-05-08 22:03:06 · 245 阅读 · 0 评论 -
C++4种类型转换
总 结 去const属性用const_cast。 基本类型转换用static_cast。 多态类之间的类型转换用daynamic_cast。 不同类型的指针类型转换用reinterpreter_cast。static_cast任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast;注:顶层const:表...转载 2019-05-13 20:59:00 · 154 阅读 · 0 评论 -
如何定义一个只能在堆上创建的类,如何定义一个只能在栈上创建的类
1.如何定义一个只能在堆上生成的类方法一:首先我们要在堆上定义一个对象的时候一定要用new ,比如A *a=new A;C++会先在堆上malloc一块内存,然后执行构造函数。相信有些人看到这个题都会这样想:class A{public: A() { return new A; }};看到这里不要笑,...转载 2019-05-13 21:09:25 · 483 阅读 · 0 评论 -
标准库函数和系统调用的区别
写在前面:所谓标准库函数,这里暂时讨论C语言的标准库函数。库函数是语言本身的一部分,而系统函数是内核提供给应用程序的接口,属于系统的一部分。函数库调用是语言或应用程序的一部分,而系统调用是操作系统的一部分。一、标准库函数和系统调用的区别 函数库调用 系统调用 在所有的ANSI C编译器版本中,C库函数是相同的 各个操作系统的系统调用是不同...转载 2019-05-13 21:24:04 · 329 阅读 · 0 评论 -
如何区分一段代码是C++还是C代码编写的
C与C++在很多地方不同,比如1.最明显的是看输入输出:C用库函数printf()和scanf(),C++用标准流类cout和cin2.最本质的是看有无类class,这也是C++与C最根本的区别当然,有的程序表面上看是C++风格的,但用的是机构化的思想,而不是面向对象的思想。最明显的区别是头文件后面不用加.h,并且C++要有命名空间,而C却没有这个概念....原创 2019-05-13 21:26:05 · 7636 阅读 · 0 评论 -
什么是回调函数,回调函数的使用场景
1.回调函数基本定义-什么是函数指针通俗来说,函数指针是一个指向特定函数的指针。函数的类型由其参数及返回类型共同决定,与函数具体名称无关。示例代码如下:int testFun1(int param1,long param2,float param3); //普通函数定义该函数的类型为int(int,long,float),该类型的函数指针可以定义为如下:int (*pTf)(in...转载 2019-05-13 21:42:10 · 2564 阅读 · 0 评论 -
C++ STL vector的实现机制
vector就是动态数组.它也是在堆中分配内存,元素连续存放,有保留内存,如果减少大小后,内存也不会释放.如果新值>当前大小时才会再分配内存.它拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当该数组后的内存空间不够时,需要重新申请一块足够大的内存并进行内存的拷贝。这些都大...转载 2019-05-05 22:54:38 · 477 阅读 · 0 评论 -
多线程如何实现通讯,如何进行同步
线程间通讯一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信。这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明。使用全局变量进行通信 由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量。对于标准类型的全...转载 2019-04-30 10:38:57 · 1158 阅读 · 0 评论 -
数组与指针的区别与联系,函数指针,指针函数,指针数组,数组指针
数组与指针的区别:C语言把内存划分成四个区,它把一般的变量和数组等存在于内存中的栈区,所以数组在C语言的定义中只是一组同类型的普通变量,即使这个变量有可能是指针。所以他的作用比指针小的很多,而指针可以指向任何区的任何数据,所以就会觉得指针和数组名很像,但是必须要注意的是,数组名只是指针中的一种,它是指针中只指向栈区的且指针的移动范围是有限的,即数组长度。而且数组在定义之初就已经有了自己的内存,...原创 2019-04-25 10:09:19 · 319 阅读 · 0 评论 -
何时编译器会自动生成默认构造函数
问题:对c++初学者来说存在一个误区,如果类没有定义任何构造函数,编译器会自动生成默认的构造函数。注意:这种说法是错误的。正确的说法:惟有默认构造函数”被需要“的时候编译器才会合成默认构造函数。那什么情况下是“被需要”的时候?以下有四种情况编译器会自动合成默认构造函数情况1含有类对象数据成员,该类对象类型有默认构造函数即:一个class含有类对象数据成员,该类对象类型...转载 2019-05-05 15:44:11 · 2101 阅读 · 1 评论 -
何时编译器会自动生成拷贝构造函数
#include <iostream>using namespace std;class A{public: A() { cout << "1" << endl; } ~A() { cout << "2" << endl; }};class B : public A{public: B() ...转载 2019-05-05 16:11:58 · 1484 阅读 · 1 评论 -
多态的作用
什么是多态?概念:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。简单的说:就是用基类的引用指向子类的对象。为什么要用多态呢?原因:我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态除了代码的复用性外,还可以解决项目中紧偶合的问题,提高程序的可扩展性.。耦合度讲的是模块模块之间,...转载 2019-04-30 09:07:54 · 6973 阅读 · 0 评论 -
什么函数不能声明为虚函数
一、首先回顾下什么是虚函数及其作用,以便更好理解什么函数不能声明或定义为虚函数:1. 定义:虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式: virtual 函数返回值类型 虚函数名(形参表) { 函数体 }2. 作用:虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义...转载 2019-04-30 09:19:34 · 2053 阅读 · 0 评论 -
系统会自动打开和关闭的3个标准的文件是
(1)标准输入----键盘---stdin(2)标准输出----显示器---stdout(3)标准出错输出----显示器---stderr原创 2019-04-30 09:33:14 · 478 阅读 · 0 评论 -
说出字符常量和字符串常量的区别,并使用sizeof 计算有什么不同
字符常量是指单个字符,字符串常量以‘\0’结束,使用运算符sizeof计算比字符常量计算结果多占一字节的存储空间。原创 2019-04-30 09:38:09 · 1416 阅读 · 0 评论 -
Windows消息系统由哪几部分构成
由以下3部分组成:1.消息队列:操作系统负责为进程维护一个消息队列,程序运行时不断从该消息队列中获取消息、处理消息;2.消息循环:应用程序通过消息循环不断获取消息、处理消息。3.消息处理:消息循环负责将消息派发到相关的窗口上使用关联的窗口过程函数进行处理。...原创 2019-04-30 09:42:27 · 976 阅读 · 0 评论 -
assert()的作用
assert()这个函数在C++中用的比较少,但是有以次面试被问及到了,我就说了个中断,然后面试官让我过了,所以记录一下,查了下资料,原来如此!assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:#include <assert.h>void assert( int expression );assert...转载 2019-04-30 09:51:59 · 636 阅读 · 0 评论 -
说一下C++的返回值优化
前言大家都知道“过早的优化是万恶之源”这句话,然而我相信其中的大多数人都不知道自己是不是在做过早的优化。我也无法准确的定义什么叫做“过早的优化”,但我相信这“过早的优化”要么是得不偿失的,要么干脆是有害无利的。今天我就想举个我认为是“过早的优化”的例子。从函数返回值为了从一个函数得到运行结果,常规的途径有两个:通过返回值和通过传入函数的引用或指针(当然还可以通过全局变量或成员变量,但我...转载 2019-05-14 11:03:41 · 524 阅读 · 0 评论 -
protected,public,private在继承中的可见性
在C++里,继承有三中方式,public、protected、private三中继承方式,我们需要记住这3种继承的可见性问题,会有两个可见性的问题,一是子类与父类的可见性,二是对象的可见性(具体更多是指对象与父类的成员可见性问题),我们必须记住,三种继承的方式都并不会影响子类成员对父类成员的访问权限,即:父类成员对子类成员的可见性是由父类自身决定的,三种继承的方式只会影响实例对象的访问可见...原创 2019-05-14 11:12:27 · 2576 阅读 · 1 评论 -
vector资源释放
1. vector容器的内存自增长与其他容器不同,其内存空间只会增长,不会减小。先来看看"C++ Primer"中怎么说:为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储。设想一下,当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间、拷贝元素、撤销旧空间,这样性能难以接受。因此STL实现者在对vector进行内存分配时,其...转载 2019-05-14 22:17:26 · 907 阅读 · 0 评论 -
说说你使用的C++11的特性
auto1.在C++11之前,auto关键字用来指定存储期。在新标准中,它的功能变为类型推断。auto现在成了一个类型的占位符,通知编译器去根据初始化代码推断所声明变量的真实类型。各种作用域内声明变量都可以用到它。例如,名空间中,程序块中,或是for循环的初始化语句中。 1 2 3 autoi=42;// i is an...转载 2019-05-12 19:09:00 · 193 阅读 · 0 评论 -
如何区分左值和右值
左值右值来自于c语言。左值:用来指代可以用在赋值表达式作则的东西,具体命名的对象、在内存中栈和堆上分配的对象,或者其他对象成员,总之就是有确定存储空间的东西。右值:指的是只能在赋值表达式右侧出现的东西,如字面值和临时对象。左值引用只能被绑定到左值,不能被绑定到右值:int a = 1;int &b = a;//正确,因为a是一个左值int &c = 5;//错误...转载 2019-05-12 19:13:12 · 682 阅读 · 0 评论 -
为什么C++访问虚函数比访问普通函数慢
原因:1.- 运行时需要得到对应类的函数的地址2.- 当在用父类的引用或者指针调用虚函数时,会先从该对象的头部取到虚函数的地址(C++标准规定虚函数表地址必须放最前),再从虚函数表中取到实际要调用的函数的地址,最终调用该函数3.- 调用虚函数,相比普通函数,实际上多了三条指令:取虚表,取函数地址,call调用。4.- 影响cpu流水线5.- 编译器不能是内联函数6.- 仅当...原创 2019-05-12 19:16:09 · 755 阅读 · 0 评论 -
为什么需要纯虚函数
通过它可以指明一个虚拟函数只是提供了一个可被子类型改写的接口。 纯虚函数是在基类中声明的虚函数,它可以在基类中有定义,而且派生类必须定义自己的实现方法。基类不能生成对象,可以使用指针或者引用派生类对象。基类不在基类中实现纯虚函数的方法是在函数原型后加“=0” virtual void funtion1()=0引入原因/纯虚函数的作用 为了方便使用多态特性,我们常常需要在...原创 2019-05-12 19:25:00 · 4147 阅读 · 0 评论 -
内联函数、构造函数、静态成员函数可以是虚函数么
都不可以。1.内联函数需要在编译阶段展开,而虚函数是运行时动态绑定的,编译时无法展开; 2.构造函数在进行调用时还不存在父类和子类的概念,父类只会调用父类的构造函数,子类调用子类 的,因此不存在动态绑定的概念;3.静态成员函数是以类为单位的函数,与具体对象无关,虚函数是 与对象动态绑定的,因此是两个不冲突的概念;...原创 2019-05-12 19:40:07 · 2134 阅读 · 0 评论 -
析构函数可以调用虚函数,构造函数为什么不可以调用虚函数
简要结论:1. 从语法上讲,调用完全没有问题。2. 但是从效果上看,往往不能达到需要的目的。Effective 的解释是:派生类对象构造期间进入基类的构造函数时,对象类型变成了基类类型,而不是派生类类型。同样,进入基类析构函数时,对象也是基类类型。所以,虚函数始终仅仅调用基类的虚函数(如果是基类调用虚函数),不能达到多态的效果,所以放在构造函数中是没有意义的,而且往往不...转载 2019-05-12 19:50:31 · 419 阅读 · 0 评论 -
析构函数可以是纯虚的么
C++中析构函数可以为纯虚函数吗?众所周知,在实现多态的过程中,一般将基类的析构函数设为virtual,以便在delete的时候能够多态的链式调用。那么析构函数是否可以设为纯虚呢?class CBase{ public: CBase() { printf("CBase()\n"); } virtual ...转载 2019-05-12 19:59:38 · 5295 阅读 · 1 评论 -
为什么需要虚继承,虚继承的实现原理
虚继承和虚函数是完全无相关的两个概念。虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝。这将存在两个问题:其一,浪费存储空间;第二,存在二义性问题,通常可以将派生类对象的地址赋值给基类对象,实现的具体方式是,将基类指针指向继承类(继承类有基类的拷贝)中的基类对象的地址,但是多重继承可能存在一个基类的多份拷贝,这就出现了二义性。虚继承可以解决...转载 2019-05-12 21:07:54 · 2643 阅读 · 0 评论 -
share_ptr的线程安全性
shared_ptr线程安全性分析正如《STL源码剖析》所讲,“源码之前,了无秘密”。本文基于shared_ptr的源代码,提取了shared_ptr的类图和对象图,然后分析了shared_ptr如何保证文档所宣称的线程安全性。本文的分析基于boost 1.52版本,编译器是VC 2010。shared_ptr的线程安全性boost官方文档对shared_ptr线程安全性的正式表述是:...转载 2019-05-14 22:12:30 · 1198 阅读 · 0 评论 -
成员函数里memset(this,0,sizeof(*this))会发生什么
this里面可能包含string之类的对象,把这些对象清零会导致非法数据。即使一个类现在是POD,维护升级之后可能就不再是POD了。因此memset(this,0,sizeof(*this))是一种危险的写法。没有virtual function,没有vtable,同时class当中没有包含其他class成员的class可以用这个。 ...原创 2019-05-14 22:10:34 · 1192 阅读 · 0 评论 -
如何使用C语言的面向对象
我们都知道,C++才是面向对象的语言,但是C语言是否能使用面向对象的功能?(1)继承性typedef struct _parent{int data_parent;}Parent;typedef struct _Child{struct _parent parent;int data_child;}Child;在设计C语言继承性的时候,我们需要做的就是把基础数据放在继...转载 2019-05-06 22:36:52 · 154 阅读 · 0 评论 -
C++有哪些数据类型,为什么long和int都是4字节
如果你测试过long和int内置类型的大小,当发现都为4字节时,可能都会产生疑问,如果都是4字节,long并没有提供更大的存储范围,那么还要long做什么用?本文如下内容将为你解开这些疑团。先简要概述以下内置类型的发展,如有疏漏,还请指正。C语言开始时只有char(8位)和int(16位)两种,后来随着发展又加入了short(16位)和long(32位),此时,int可以是16位...转载 2019-05-06 22:39:43 · 1671 阅读 · 0 评论 -
函数调用类型_cedecl,_stdcall,_fastcall
简介:_cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。_stdcall 是StandardCall的缩写,是C++的标准调用方式:所有参数从右到左依次入栈...转载 2019-05-06 22:44:19 · 443 阅读 · 0 评论 -
什么是序列化和反序列化
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为对象。把对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为对象的过程称为对象的反序列化。序列化就是一种用来处理对象流的机制,所谓对象流也就是将...原创 2019-05-06 22:47:03 · 143 阅读 · 0 评论 -
用预处理指令声明一个常数,用以表明1年终有多少秒
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情: #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。意识到这个表达式将使一个16位机的整型数溢出-因此要用到长...转载 2019-05-06 22:51:18 · 785 阅读 · 0 评论 -
C++中为什么用模板类
1:可用来创建动态增加或减少的数据结构2:它与某种特定类型无关,因此代码可重复使用3:它在编译时检查数据类型而不是运行时检查数据类型,保证了类型的安全4:它是平台无关的,具有很好的移植性...原创 2019-05-14 21:57:14 · 2077 阅读 · 1 评论