C++基础
水中鱼_自由
123
展开
-
vscode配置c++代码提示补全
vscode配置c++代码提示补全在网上找了大半天,说的方式都试过了,都没有适合我的,还是自己找stackoverflow靠谱点{ "editor.rulers": [ 80 //一行限制80字符 ], "editor.tabSize": 2,//默认tab是2个字符 "editor.detectIndentation": false,//取消自动缩进 "editor.fontFamily": "monospace",//设置为等宽字体,保证代码字体显示大小 "C_Cpp原创 2022-04-22 16:59:27 · 4306 阅读 · 2 评论 -
vector中emplace_back和push_back详解,源码解读
C++11之前:通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中。原来的临时变量释放。这样造成的问题是临时变量申请的资源就浪费。C++11之后:引入了右值引用,转移构造函数(请看这里)后,push_back()右值时就会调用构造函数和转移构造函数。emplace_back:源码:主要看有注释的地方,通过完美转发,最终到构造对象,找到对应的构造函数进行构造 template<clas原创 2022-03-08 11:38:57 · 2374 阅读 · 0 评论 -
dll库直接使用 lib载入和LoadLibrary载入的区别
lib 是dll的导入库,在vs工程中添加对应lib和头文件就可以这个方法很简单,但是有2个缺点:1 程序一开始运行就需要载入整个dll,无法载入程序就不能开始运行;2 由于载入的是整个dll,需要耗费资源较多LoadLibrary载入,是对应的 “动态加载”方式,它不在程序运行时候载入dll,不需要lib导入,使用程序函数 LoadLibrary 载入库,并使用 API 获得...原创 2019-12-18 14:54:43 · 1837 阅读 · 0 评论 -
typedef 和define的区别
1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错。2)typedef是在编译时处理的。它在自己的作用域内给一个已经存在的类型一个别名#define int_ptr int * //没有分号,若有,则会连分号一起替换int_ptr a, b; //相当于int * a, b; 只是转载 2016-08-29 21:49:30 · 318 阅读 · 0 评论 -
函数式宏定义和普通函数的区别
在C及C++语言中允许用一个标识符来表示一个字符串,称为宏,该字符串可以是常数、表达式、格式串等。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。若字符串是表达式,我们称之为函数式宏定义。 我们以下面两行代码为例,展开描述: 函数式宏定义:#define MAX(a,b)转载 2016-08-29 16:22:47 · 3736 阅读 · 0 评论 -
strcpy与memcpy的区别
原型声明:extern char *strcpy(char *dest, const char *src); 头文件:#include转载 2016-08-29 16:02:12 · 1013 阅读 · 0 评论 -
如何重载前置++和后置++
前置++:即++运算符位于操作数的前面,例如:++i; 后置++:即++运算符位于操作数后面,例如:i++; 注意一下几点: 1、前置++重载时没有参数,而后置++重载时有参数。不会使用其参数,仅仅是区分用。可以理解为前置++后面有参数了,所以不需要参数 2、前置++需要返回引用,因为重载自加运算符后可以返回对象的引用, 以方便在表达式中连续使用。而后置++返回的不是引用,所以不能进行连续使原创 2016-08-29 15:53:25 · 11365 阅读 · 6 评论 -
delete和delete[]的区别
转载地址:http://blog.csdn.net/hazir/article/details/21413833 C++中,类型分为两种:内置类型和自定义的类类型。在释放内存时分为释放内置类型和自定义类型的数组。 1、对于单个对象,释放内置类型和类类型的方法一样,使用delete.对于类对象而言,delete做两件事: (1)调用类的析构函数; (2)释放对象的内存;转载 2016-08-29 14:58:23 · 448 阅读 · 0 评论 -
5分钟搞定内存字节对齐
写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字节对齐吧./********************分割线如果体系结构是不对齐的,A中的成员将会一个挨一个存储,从而sizeof(a)为11。显然对齐更浪费了空间。那么为什么要使用对齐呢? 体系结构的对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。假转载 2016-08-28 10:55:18 · 433 阅读 · 0 评论 -
struct字节计算
若结构体为空,其大小为1; 若不为空,结构体的存储比较复杂,并不是简单的字节相加,比如:struct student { char name; int id; double score; }; 按照我们一般的想法结构体的字节数sizeof(student)=1+4+8=13,然而我们在代码中验证后就会发现sizeof(student)=16;这是为什转载 2016-08-28 10:37:58 · 3342 阅读 · 0 评论 -
operator =注意事项
重载操作符,遵循的规则是 A& operator =(const A& rhs);在重载=时,1、要考虑证同情况即自我赋值,即A a; a=a; 2、考虑异常安全的情况,避免内存分配失败,例如:A& operator =(const A& rhs){ if(this == &rhs) return this;//证同 delete pb;//pb是A中的一个成员变量BitMap原创 2016-04-16 16:09:22 · 476 阅读 · 0 评论 -
如何防止类被继承
方法有一下两种: 1、将类后面加一个final关键字,最简单; 2、利用私有构造函数,然后提供public的方法创建对象或者设定友元。 重点说说方法2: (1)将构造函数设为私有,提供public方法进行对象的创建,利用的是单例模式。 (2) 将构造函数设为私有,通过设定友元来进行创建对象,代码如下:class A;class Usable_lock{friend class A;p原创 2016-08-29 16:54:35 · 1234 阅读 · 1 评论 -
#,##,...
C/C++中,#,##,二者用在宏定义中# 表示:将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后变成一个字符串##表示:为连接符,把宏参数名与宏定义代码序列中的标识符连接在一起,形成一个新的标识符例如:#define PRINT( n ) printf( "token" #n " = %d", token##n )//##为连接符,tok原创 2016-08-29 17:25:47 · 498 阅读 · 0 评论 -
struct在C和C++中的区别
在C中: 1、struct用户自定义数据类型,只能是一些变量的集合体,可以封装数据却不可以隐藏数据,而且成员不可以是函数。 2、struct是没有权限设置的。 3、必须在结构标记前加上struct才能作为结构类型名进行定义变量。在C++中: 1、struct抽象数据类型,支持成员函数的定义。 2、struct的默认权限是pulic。 3、结构标记可以直接作为结构类型名原创 2016-08-29 20:38:17 · 466 阅读 · 0 评论 -
智能指针auto_ptr、内存泄漏解决
在C++11中,已经不使用auto_ptr,而用 unique_ptr进行替代,不过二者原理都差不多。头文件:memory智能指针:实质上是一个类,在创建智能指针的时候,本质上是在栈上创建了一个对象,而析构函数总是会在出栈时被调用,清理会自动进行。unique_ptr(auto_ptr)通过在栈上构建一个对象a,对象a中动态分配内存指针p,所有对指针p的操作都转为对对象a的操作。而在a的析构函数中原创 2016-08-29 20:02:14 · 2598 阅读 · 0 评论 -
类和函数模板特例化
引入原因:编写单一的模板,它能适应大众化,使每种类型都具有相同的功能,但对于某种特定类型,如果要实现其特有的功能,单一模板就无法做到,这时就需要模板特例化。 定义:是对单一模板提供的一个特殊实例,它将一个或多个模板参数绑定到特定的类型或值上。函数模板特例化:必须为原函数模板的每个模板参数都提供实参,且使用关键字template后跟一个空尖括号对<>,表明将原模板的所有模板参数提供实参。templa原创 2016-08-30 20:37:07 · 5458 阅读 · 1 评论 -
C++虚函数表
转载一篇大牛文章 作者:陈皓 地址:http://blog.csdn.net/haoel/article/details/1948051前言C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算转载 2016-08-30 22:04:21 · 293 阅读 · 0 评论 -
class字节计算
1、类的大小类的sizeof()大小一般是类中的所有成员的sizeof()大小之和,这个就不用多说。确切的说,用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小。注意:类只是一个类型定义,它本身是没有大小可言的。对象大小= vptr(类中定义了多个virtual函数,仍然为占用4个字节) + 所有非静态数据成员大小 + Aligin字节大小(依赖于不同的编译器)。转载 2016-08-28 11:27:08 · 1053 阅读 · 0 评论 -
LINK:fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
在安装了VS2013的情况下,后又安装了VS2010,出现此类错误。解决办法如下: 第一步: 打开该项目——项目属性——配置属性——连接器——清单文件——输出输出——嵌入清单 “是”改为“否”。 第二步:若为64位的操作系统,则失效的根本原因是cvtres.exe版本冲突,将新安装的VS2010的安装目录下的cvtres.exe用VS2013中的cvtres.exe进行替换。注意,这里指的原创 2017-04-03 13:15:00 · 315 阅读 · 0 评论 -
加载含有依赖其他dll库的dll
当编写的dll依赖其他dll库时,exe在加载这个dll时,exe会去找这个dll所依赖的其他dll,而查找目录只是其exe所在的目录或指定的那几个系统目录。不会在你放置的dll目录中找。 例如: A.dll依赖B.dll,把A.dll和B.dll放置在d:\load_dll目录下,当E:\debug\C.exe执行::LoadLibraryA("d:\\load_dll\\A.dll")原创 2018-02-03 18:42:26 · 6107 阅读 · 0 评论 -
继承、重载、多态
在C++中,重载和多态是一个概念:都是可以有多个同名函数,只是参数类型和参数个数不一样。 继承:是针对类来说,子类继承父类,函数是一个纵向过程,子类的函数可以对父类的函数进行重写,可以针对不同的子类函数实现不同的具体功能。而多态则是一个横向过程,同一函数可以表现出不同的行为。 什么是面向对象:面向对象主要有四大特征: 1、抽象性:是对一个类的行为的功能抽象。 2、继承性:类可以被继承 3、原创 2016-03-24 21:47:03 · 408 阅读 · 0 评论 -
C++ 静态成员初始化
在C++ 类中,静态成员一般不允许在类声明中进行初始化,应该在类的外部进行初始化,例如:class A{public: static int a;};static int A::a=0; //初始化方式void main(void){ int b=0; b=A::a;//使用,无需定义相关类的变量而直接使用之。}但是有一个例外,可以为静态成员提供const原创 2016-07-16 09:28:53 · 445 阅读 · 0 评论 -
指针和引用
引用:本质是一个变量的别名,它和该变量绑定在一起,在定义引用时,必须使用相应的变量进行初始化,否则会编译错误。例如: int &a;这样就会编译错误,int &a = ival;ival为整型这样正确。 指针:其本身就是一个对象,它占用地址空间, 区别是:第一,本身是对象,允许对指针进行赋值和拷贝,在其生命周期内可以指向不同的对象,而引用则不能;第二:指针无须在定义时赋初值,而引用必须付初值。原创 2016-03-27 21:41:53 · 208 阅读 · 0 评论 -
constexpr和decltype
constexpr:将变量声明为constexpr类型以便编译器来验证变量的值是否是一个常量表达式,C++11允许定义consexpr函数,这种函数要足够简单以使得编译时就可以计算其结果. decltype:类型指示符,作用是选择并返回操作数的数据类型。例如decltype(f()) sum = x;sum的类型就是函数f的返回类型。参数可以是一个变量或函数,注意:decltype((variab原创 2016-03-27 21:36:33 · 341 阅读 · 0 评论 -
char,short,int,long等数据类型
char:占一个字节,8位 short:占两个字节,16位 int:一般占一个机器字节,对于16位操作系统,则占16位,即2个字节,32位操作系统则占32位,即4个字节,64位操作系统为了向下兼容,也是32位。 long:只是规定了最小和int型一样大一般占1个或2个机器字节原创 2016-03-27 20:48:06 · 662 阅读 · 0 评论 -
SGI 内存池
内存池:是解决内存碎片的主要方法,由于new和malloc是直接从操作系统那里通过其算法申请内存,每次申请操作系统都要执行一次,所以申请效率不仅不高,而且频繁的申请与释放内存会形成大量的内存碎片。而内存池的主要思想就是在初始化时就分配一大块内存给程序,当需要内存时,就从这一大块中切给程序,当释放时,也是释放到内存池中,并没有释放给操作系统。这样会大大的减少内存碎片,因为所有的内存操作都只在这个内存池原创 2016-04-09 11:00:25 · 622 阅读 · 0 评论 -
C++ 内存
C++中内存的分配有:内存池,静态内存和栈内存。 静态内存:用来保存局部static对象,类中static变量,以及全局变量; 栈内存:保存定义在函数内部的非static变量,对象。 分配在静态内存或栈内存中的对象和变量由编译器自动创建和销毁,对于栈对象和变量,仅在所定义的程序块运行时才存在,离开该代码块,则自动销毁。而对于静态内存中的变量和对象,则在使用之前就对之分配内存,在整个程序结束时才原创 2016-03-25 14:51:31 · 221 阅读 · 0 评论 -
浅谈C++友元
友元函数或类用于访问另一个类中的非公有成员(私有和受保护),这是从外部访问类内部非公有成员的唯一方法。下面以友元函数为例进行说明。首先,该函数是属于类外部独立的函数,要想访问类内部非公有成员,就要在类的内部进行友元声明,声明方式就在函数类型之前加friend即可。并且friend不受任何访问说明符(private等)的约束,在哪里都可以声明,但习惯是在所有的访问说明符之前声明友元函数,注意:这个声明原创 2015-12-10 20:48:37 · 325 阅读 · 0 评论 -
C++ 访问属性
对于类的继承,有public,protect,priavte.public 不用说。 private:类中成员是此属性,则表明这个成员只属于此类,只有此类里面的成员函数可以操作,其他任何情况都不允许操作; protected:此类成员,对于类的用户(即实例化的对象)不能操作,但是对于其派生类可以操作,注意,无论是什么继承类型的访问说明符,即使继承类型为private,例如:class sub:p原创 2016-04-01 11:42:23 · 1423 阅读 · 0 评论 -
基类和派生类
如果基类base中有虚函数,派生类sub继承基类,在初始化时: 1、通过类定义的基类对象,用派生类去初始化基类时,基类对象不会转化为派生类对象,即基类对象调用的函数还是自己内部写的; 2、通过指针,定义的基类对象,用派生类去初始化时,会将此基类对象转化为派生类对象,即调用的重载函数是派生类内部的函数,和基类的函数无关。即:基类的指针或引用可以绑定的派生类对象上,这也就对于工厂模式最好的利用。可以原创 2016-03-31 21:16:19 · 858 阅读 · 0 评论 -
C++ 多态
多态性:即把具有继承关系的多个类型(不同派生类)称为多态类型,因为我们能使用这些类型的”多种形式”而无需在意他们的差异。指针和引用的静态类型和动态类型不同是C++支持多态性的本质。 当我们使用基类的指针或引用调用基类中定义的一个函数时,我们并不知道该函数真正作用的对象是什么类型,因为他可能是一个基类的对象,也可能是一个派生类的对象。如果该函数是虚函数,则直到运行时才会决定到底执行哪个版原创 2016-03-31 21:52:48 · 223 阅读 · 0 评论 -
lamabda表达式
定义:可以理解为一个未命名的内联函数。他一般定义在某个函数的内部。其具体形式如下: [capture list] (parameter list) -> return type {function body;} 其中:capture list是捕获列表,捕获lamabda所在函数定义的局部变量,可以为空,如果有,则在函数体中会用到此变量,此变量的值是调用此lamabda之前最后一次改变的值。pa原创 2016-03-27 21:52:15 · 1839 阅读 · 0 评论 -
socket
在网络编程中,由于各个主机的存储方式不一样,为了进行统一,用的字节序都是网络字节序即大端字节序。如果使用TCP/IP协议进行网络编程,由于TCP/IP是用字节流的方式,所以传输的数据不用对字节序进行变换。只需要对IP和端口转换成网络字节序即可。由htons,htonl函数进行转换。而网络字节序转换为主机字节序由函数ntohs,ntohl函数完成。记法:h表示主机,n表示网络,s表示短整型,用于端口,原创 2016-04-11 16:02:21 · 267 阅读 · 0 评论 -
C++线程池
一般用于服务器,防止建立过多的线程导致系统响应慢等。线程池主要由以下几个部分组成: 任务接口:用于具体任务重载,使线程池中的线程获取其任务; 工作线程:用于创造一个线程,并用线程从任务列表中获取任务并执行; 线程管理器:用于管理线程类创建的线程。即线程池管理器,此类内包括了工作线程类,任务列表,线程列表(即线程池)。利用线程管理器,实现开启工作线程,管理线程池(负责对线程池里面的线程进行添加或转载 2016-04-23 20:57:14 · 320 阅读 · 0 评论 -
回调函数
回调函数的主要目的就是为了在多个模块之间进行解耦合。 回调函数定义:简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数,就是由你自己写的。你需要调用另外一个函数,而这个函数的其中一个参数,就是你的这个回调函数名。这样,系统在必要的时候,就会调用你写的回调函数,这样你就可以在回调函转载 2016-05-17 11:27:23 · 280 阅读 · 0 评论 -
class和typename
在c++Template中很多地方都用到了typename与class这两个关键字,二者在声明模板类时使用含义是一样的。但是在嵌套依赖类型中,只能使用typename来表明它是一个类型而不是成员变量。template <class T>class MyArray { public:typedef int LengthType;//嵌套类型.....}template<class T>v转载 2016-05-05 20:52:48 · 309 阅读 · 0 评论 -
浅拷贝和深拷贝
浅拷贝是系统默认的构造函数,而深拷贝是用户自定义的函数。二者的主要区别在于指针的赋值。 浅拷贝,只是对指针的拷贝,拷贝后与复制前的对象中所值得指针,即两个指针指向同一个内存空间,导致在进行析构函数时,对指针进行两次析构,会导致系统出错。深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。这样析构函数就不会报错原创 2016-05-04 22:21:55 · 199 阅读 · 0 评论 -
正则表达式
1、{d}表示单个数字,{d}{n}表示一个n个数字的序列。(如,{d}{3}匹配三个数字的序列) 2、在方括号中的字符集合表示匹配这些字符中的任意一个。如[- .]匹配一个短横或一个空格或一个点,注意,点在括号中没有特殊含义 3、后接?的组件是可选的。如,{d}{3}[- .]?{d}{4}匹配这样的序列:开始是3个数字,后接一个短横或空格或点,然后是4个数字,但[- .]是可选的,也就是说可原创 2016-04-19 20:40:54 · 253 阅读 · 0 评论 -
强制转换的4种类型
在C++中,新式转换有4种,尽量使用新式转换,这样容易检测错误。新式转换都类似模板,并且带有cast。T为要转换出的目标类型const_cast(expression):将对象的常量性消除;dynamic_castT>(expression):执行“安全向下转型”,决定某对象向其派生类对象转型,这个转型付出的代价最大,运行速度最慢;static_castT>(expression):强原创 2016-04-18 22:30:03 · 1048 阅读 · 0 评论 -
C++ 抽象基类
纯虚函数:纯虚函数无须定义,即不需要函数体,只需要在虚函数的参数列表后面添加 = 0;即可。例如:virtual double net(int n) = 0; 抽象基类:含有(或者未经覆盖直接继承)纯虚函数的类是抽象基类。抽象基类负责接口的定义,后续的派生类可以覆盖该接口,即重写虚函数和纯虚函数。注意:由于抽象基类含有纯虚函数,它没有函数体,所以不能对抽象基类进行实例化,只能对其派生类进行实例化原创 2016-04-01 11:15:38 · 1035 阅读 · 0 评论