![](https://img-blog.csdnimg.cn/20201031204324547.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
C++语言特性
文章平均质量分 61
主要解析C++语言的特性
马小超i
你若盛开 清风自来
展开
-
进出容器会调用对象的拷贝和析构
而当这个对象出容器时,容器认为此 对象没有用处,会调用其析构函数。一个对象放入容器,调用了其拷贝构造函数,生成了一份新的;所以,当你拿引用去接收一个容器内的东西,用完之后再出容器。不然会segmentation fault。原创 2022-09-22 15:59:36 · 343 阅读 · 1 评论 -
C++11新特性:lambda表达式
Lamda表达式C++ 11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。一个完整的 Lambda 表达式如下:[=] (int x, int y) mutable -> int { int z = x + y; return z; }[函数对象参数] (操作符重载函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}可以看到,Lambda 主要分为五个部分:[函数对象参数](操作符重载函数参数)mut原创 2021-10-13 10:34:54 · 777 阅读 · 0 评论 -
C++11新特性列表初始化
在我们实际编程中,我们经常会碰到变量初始化的问题,对于不同的变量初始化的手段多种多样,比如说对于一个数组我们可以使用 int arr[] = {1,2,3}的方式初始化,又比如对于一个简单的结构体:struct A{ int x; int y;}a={1,2};这些不同的初始化方法都有各自的适用范围和作用,且对于类来说不能用这种初始化的方法,最主要的是没有一种可以通用的初始化方法适用所有的场景,因此C++11中为了统一初始化方式,提出了列表初始化(list-initializati...原创 2021-08-20 10:26:06 · 354 阅读 · 0 评论 -
怎样牢牢记住指针常量和常量指针的区别【const int *和int const*和int* const】
const int *int const*int* const这三个具有很大的迷惑性,怎么区分他们呢?为了方便,我们假设有指针p,const int *pint const*pint* const p区分这三种的方法就是 只看const 和 * 和指针的名字,不看数据类型 int!第一个和第二种情况:const 的右边是 *p ,*p 是指针指向的值, 也就是说const 修饰的是这个指针指向的值,所以表达的意思就是 此指针指向的值 要看做一个常量,那么就无法通过指针原创 2021-08-12 15:10:36 · 183 阅读 · 0 评论 -
计算机中基本数据类型的存储结构(unsinged为什么不能修饰double?)
目录二进制整数的存储有符号数无符号数计算机以补码来存储整数浮点数的存储尾数的规整化移码存储结构字符型的ASCLL码表示修饰符unsinged二进制计算机中的数据都是以二进制补码形式存储的。为什么是二进制不是八进制十进制呢?因为二进制在现实世界可以用电器元件很容易的实现,并且受磁场等干扰最小。计算机最底层是用电来控制电子元器件以此表达二进制,电器元件的高电平和低电平分别对应二进制的1和0。1个元器件表示的一位二进制称为1比特(Bit)或1位,8个原创 2021-01-22 18:50:03 · 1951 阅读 · 0 评论 -
C++中的转义字符(字符串中反斜杠\的特殊性)
转义字符的作用今天在处理字符串的时候,遇见了平时在字符串中并不常见的字符---反斜杠\ 。与反斜杠搭配的一些特殊字符称为转义字符,转义字符可以表示特殊的意义,或者表示不容易表示的字符。比如说我们想定义一个带有双引号的字符串 s="abc";s="abc" 这样s输出是没有双引号的。 s=" "abc" " 这样连编译都不通过出现这个问题的原因是双引号原本就是表示字符串的边界的,所以处理起来格外棘手。有了转义字符,直接在双引号前加上\, \" 就是一个表示双引号的转义字符,问题一下子.原创 2021-01-21 16:35:37 · 26901 阅读 · 1 评论 -
C++中inline内联函数和宏之间的区别
inline函数是C++引入的机制,目的是解决使用宏定义的一些缺点。1.为什么要引入内联函数(内联函数的作用)用它替代宏定义,消除宏定义的缺点。宏定义使用预处理器实现,做一些简单的字符替换,因此不能进行参数有效性的检测。另外它的返回值不能被强制转换为可转换的合适类型,且C++中引入了类及类的访问控制,在涉及到类的保护成员和私有成员就不能用宏定义来操作。2.inline相比宏定义有哪些优越处(1)inline函数代码是被放到符号表中,使用时像宏一样展开,没有调用的开销效率很高;...原创 2021-01-20 10:22:52 · 276 阅读 · 0 评论 -
C++ pair的基本用法
pair的应用pair可以将2个数据组合成一组数据,当有这样的需求时就可以使用pair。如STL中的map就是将key和value放在一起来保存;当一个函数需要返回2个数据的时候,也可以选择pair。pair的实现pair的本质是一个结构体struct,主要的两个成员变量是first、second。其标准库类型--pair类型定义在#include <utility>头文件中,定义如下:类模板:template<class T1,class T2> struc原创 2020-12-23 17:12:06 · 583 阅读 · 0 评论 -
用new创建二维数组不可以直接memset
用new创建二维数组不可以直接memsetmemset可以将数组初始化,不管是一维数组还是二维数组。但是其前提是数组空间必须是连续的。new一次出的空间是连续的,但是多次new出的空间不一定是连续的,所以不能直接使用memset初始化。看如下例子:#include<iostream>using namespace std;int main(){ int n=5; int m=10; //new申请二维数组 int** a=NULL; a=new int* [n]原创 2020-12-21 15:45:15 · 596 阅读 · 0 评论 -
C++的this指针【定义、用法、本质、特点】
一、this指针的定义及用法我们知道在C++中成员变量和成员函数是分开存储的,每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码。那么问题是:这一块代码是如何区分哪个对象调用自己的呢?C++通过提供特殊的对象指针,this指针,解决上述问题。this指针指向被调用的成员函数所属的对象this指针是隐含每一个非静态成员函数内的一种指针,this指针不需要定义,直接使用即可。this指针的用途:当形参和成员变量同名时,可用this指针来区分 在类的非静态成原创 2020-12-21 15:02:44 · 16484 阅读 · 5 评论 -
怎么理解C++多态的“父类指针或引用指向子类对象”?
动态多态动态多态的实现是通过子类重写父类的虚函数实现的。动态多态需要满足的条件:有继承关系 子类重写父类中的虚函数动态多态的使用方法:父类指针或引用指向子类对象假设我们现在有如下的类,其中Animal为基类,Cat和Dog都是其派生类。class Animal{public: virtual void speak(){ cout << "动物在说话" << endl; }}; class Cat :public Animal{pub.原创 2020-12-15 18:19:36 · 18593 阅读 · 7 评论 -
哪些函数不可以成为虚函数?构造函数和析构函数可以是虚函数吗?
哪些函数不能成为虚函数?普通函数:普通函数不属于成员函数,是不能被继承的。普通函数只能被重载,不能被重写,因此声明为虚函数没有意义。因为编译器会在编译时绑定函数。 构造函数:只有当调用了构造函数,这个对象才能产生,如果把构造函数写成虚函数,这时候我们的对象就没有办法生成。更别说用对象去调用了。所以构造函数不能成为虚函数。 静态成员函数:静态成员函数是属于类的,不依赖于对象调用,所以也不能成为虚函数。 友元函数:友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。 内联原创 2020-12-09 20:11:53 · 997 阅读 · 0 评论 -
C++的虚函数表和动态绑定分析
什么是虚函数表?每个包含了虚函数的类都有一个虚函数表(简称虚表)。虚表是一个指针数组,其元素是虚函数的指针,每个元素对应一个虚函数的函数指针。需要指出的是,普通的函数即非虚函数,其调用并不需要经过虚表,所以虚表的元素并不包括普通函数的函数指针。虚函数指针的赋值发生在编译器的编译阶段,也就是说在代码的编译阶段,虚表就可以构造出来了。如下代码,类 A 包含虚函数vfunc1,vfunc2,由于类 A 包含虚函数,故类 A 拥有一个虚表。class A {public: virtual原创 2020-11-30 21:02:18 · 302 阅读 · 0 评论 -
虚函数和纯虚函数的比较
虚函数: virtual void speak(){ cout << "动物在说话" << endl; }在类的成员函数前面加上virtual关键字,就构成了虚函数。子类通过重写基类的虚函数来实现多态。纯虚函数:virtual void speak()=0;在虚函数的形参后面写上=0,则虚函数变为纯虚函数,纯虚函数不需要实现,包含纯虚函数的类叫抽象类(也叫接口类),抽象类不能实例化对象。子类必须重写基类中的纯虚函数才能实例化出对象。...原创 2020-12-11 02:18:31 · 367 阅读 · 0 评论 -
C++和C的程序互相调用要使用 extern “C“
函数重载C语言中,函数是不允许重载的,而在C++中,函数可以重载。这也是为什么C和C++函数编译方式不同的原因。例如,假设某个函数的原型为:void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字_foo_int_int 这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数void foo( int x, int y )与void foo原创 2020-12-13 23:06:01 · 360 阅读 · 0 评论 -
面试中常问的strcpy()函数相关【溢出、手写、返回值】
目录标准库函数中的strcpy()源码strcpy()的用法strcpy()的问题缓冲区溢出问题内存重叠问题总结手写实现strcpy()strcpy()为什么返回指针?函数strncpy()标准库函数中的strcpy()源码strcpy是一种C语言的标准库函数。strcpy是string copy 字符串复制的缩写。char *strcpy(char *strDest, const char *strSrc)简单的理解:源字符串strSrc的内容复制给目标字符串原创 2020-12-11 20:54:01 · 1590 阅读 · 0 评论 -
从内存层面看char *p和char p[]的区别
char p[]="hello":p[]是一个字符串数组,编译器在栈上给p[]分配6字节的空间,6字节中依次存储'h','e','l','l','o','\0'。 但不存在p指针本身的存储。p是一个数组内存块的名字。 字符串是可以修改的。char *p="hello" :p是指向一个常量字符串的指针 ,编译器在栈上给p分配4字节(如果是32位),而字符串"hello"存放在静态存储区。 字符串是不能修改的。下面的例子:#include<iostream>using...原创 2020-12-10 22:51:35 · 522 阅读 · 0 评论 -
C++兼容C语言的遗留问题探讨:char *p=“hello“;
在C++中,char *p="hello"; 这种写法是否正确呢?我们测试下,如下所示代码: char *p1="hello"; cout<<p1<<endl; cout<<(void *)p1<<endl;编译、运行代码,结果如图:p1输出为hello,p1的地址为0x488001,看起来这个代码没什么问题。警告:虽然代码可以执行,但是值得注意的是,此时编译器给出了一个警告:[Warning] deprecated ..原创 2020-12-10 22:01:05 · 1754 阅读 · 0 评论 -
C++中二进制 八进制 十进制 十六进制的表示方法
我们都知道,在使用printf输出整数时,可以选择输出的进制形式。(要注意的是,打印二进制数并没有现成的格式,只能自行编写函数打印。) int a=100; printf("%b\n",a); //错误,没有二进制 printf("%o\n",a); //八进制 printf("%d\n",a); //十进制 printf("%x\n",a); //十六进制 同样的,对于一个整型的变量,我们也可以用不同的进制形式给其赋初始值。 int a=0b100; //二进制原创 2020-12-07 19:28:43 · 3264 阅读 · 0 评论 -
class类的大小计算【空类,虚函数类,继承】
1、类的大小首先必须先了解class的对齐问题,class和struct的对齐规则一样 :struct的用法和struct的对齐原则这里我们所说的类的大小,也就是类的空间占用,所以类的大小和该类对象的大小始终都是一致的。那么哪些因素可以影响类的大小,哪些是无关紧要的因素呢?有关的因素:普通成员变量:在实例对象中存在,需要注意对齐问题。 虚函数:有虚函数的类就会有虚函数表,类的每个实例对象都有一个vptr指针指向虚函数表。 继承(单一继承,多重继承,重复继承,虚拟继承):子类会继承父类的原创 2020-12-09 21:23:45 · 838 阅读 · 2 评论 -
struct的用法和struct的对齐原则
struct用法:struct在C语言中作为结构体。结构体定义:struct stu{ char job[20]; int age; float height;};使用: struct stu a; //或者省略关键字struct stu a;也可以定义和使用同时:struct stu{ char job[20]; int age; float height;} a;在后续使用中,出现结构体类型的原创 2020-11-25 18:56:50 · 1225 阅读 · 0 评论 -
手动实现类中的默认函数【构造函数,析构函数,复制构造函数、赋值操作符重载】
类中的默认函数假设我们现在有如下一个学生类。string类型的名字变量 int类型的年龄 int类型的科目数量 指针类型的成绩 还有一个成员函数show(),可以输出这个学生的基本信息。class stu{public: void show(); //输出学生的基本信息private: string name; //姓名 int age; //年龄 int num; //科目数量 int *src; //num科的成绩分别为src[i]};v..原创 2020-12-15 01:15:46 · 293 阅读 · 0 评论 -
C++中有hash_map吗?hash_map和unordered_map
关于hash_mapmap是C++提供的关联容器,可方便地存取键值对。map底层实现为红黑树,它是一种自平衡的二叉排序树。map中的元素会按照键的值进行“排序”。更详细的解释:C++STL中map的底层实现和使用这恰好能满足我们需要对数据进行排序的应用需求,而且足够高效,其查询操作的复杂度是 O(logN) 。但有时候我们可能不需要对数据进行排序,而仅仅是通过key能“快速”获取value,想用更快的hash算法【查询复杂度O(1)】来实现。这个时候就需要hash_map出场了。C++.原创 2020-11-14 14:57:58 · 575 阅读 · 0 评论 -
C++的读入和输出在文件和操作窗口间的切换【freopen和ifstream、ofstream】
在调试过程中,经常需要使用文件读入和文件输入,有时还需在文件和窗口间切换读入和输出。以下总结freopen和ifstrem的用法。freopen语句文件读入语句为: freopen("abc.in","r",stdin); .... fclose(stdin);上述语句 freopen("abc.in","r",stdin); 的作用是把标准输入流重定向到一个名为abc.in的文件中,这样在用scanf或是用cin输入时便不会从标准输入流读取数据(也就是不会从C++操作窗口原创 2020-11-04 18:16:08 · 1442 阅读 · 1 评论 -
C++关键字protected的作用详解
一般的,类的成员是私有成员(private)或者公有成员(public)。还可以用 protected 访问范围说明符修饰,从而成为“保护成员”。保护成员的可访问范围比私有成员大,比公有成员小。能访问私有成员的地方都能访问保护成员。保护成员扩大的访问范围表现在:基类的保护成员可以在派生类的成员函数中被访问。引入保护成员的理由是:基类的成员本来就是派生类的成员,因此对于那些出于隐藏的目的不宜设为公有,但又确实需要在派生类的成员函数中经常访问的基类成员,将它们设置为保护成员,既能起到隐藏的目的,又避免了派原创 2020-11-23 11:01:29 · 14047 阅读 · 1 评论 -
C++关键字extern的用法:一个文件中的变量或函数在其他文件中调用
在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”。extern声明不是定义,即不分配存储空间。在一个文件中定义了变量和函数, 在其他文件中要使用它们, 可以有两种方式:1.使用头文件,在声明这些变量和函数,然后其他文件去包含头文件2.在其他文件中直接extern。程序设计风格:1.不要把变量定义放入.h文件,这样容易导致重复定义错误。2.尽量使用static关键字把变量定义限制于该源文件作用域,除非变量被设计成全..原创 2020-09-16 18:15:47 · 5388 阅读 · 0 评论 -
C++关键字static的用法【分别修饰变量和函数、内部机制】
static用来控制变量的存储方式和可见性函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此 函数控制)。需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不原创 2020-07-26 10:57:52 · 273 阅读 · 0 评论 -
C和C++中const的用法【修饰变量、修饰函数参数、修饰函数返回值、常函数、常对象】
一、修饰普通变量const int 和 int const在修饰普通的变量类型(除指针)作用是相同的。如下a,b都是int型常量,不能被修改。int const a=5;const int b=10;二、修饰指针1. 常量指针:const int* 和int const *只要const位于*的左侧,无论它在类型名的左边或右边,都声明了一个指向对象的指针,叫做常量指针。 int a=10; int *q=&a; const int *p=&a;定义.原创 2020-10-24 17:55:59 · 613 阅读 · 2 评论 -
C++ 使用rand()函数生成随机数
生成随机数需要rand() 和srand() 一起使用,其中 srand() 用来初始化随机数种子, rand() 用来产生随机数。rand函数--随机数发生器:用法:int x=rand(); 可以产生一个0~32767之间的随机数。生成一定范围的随机数:a + rand() % n;其中的 a 是起始值,n 是整数的范围。例如生成[a,b]之间的随机数,int x=a + rand()%(b-a+1);随机小数:可以先随机整数,再除以精度。超范围:如果范围大于32767...原创 2020-10-06 10:54:51 · 12605 阅读 · 0 评论 -
C++中class和struct的区别
C++被称为“C with class”,可见在C++中class是多么重要,与class类似的一个结构就是struct了,struct最早是在C语言中出现的,在C++中对struct的功能也进行了扩展,下面就来说一说struct和class的区别吧:1、默认的继承权限struct默认是公有继承(public),class默认是私有继承(private)2、关于默认访问权限class中默认的成员访问权限是private的,而struct中则是public的。3、关于大括号初始化问题s转载 2020-09-16 21:10:32 · 1013 阅读 · 0 评论 -
C++程序的联合编译
三个文件:array.h#ifndef ARRAY_H#define ARRAY_H#include<iostream>using namespace std; void sameful(int *a,int n,int x); // 将数组的所有元素设置为一指定值 void add(int *a,int *b,int *c,int n); //合并两个数组的内容 int find(int *a,int n,int x); //查找某个数在数组中的位置 int del原创 2020-09-16 13:12:54 · 2770 阅读 · 3 评论 -
宏定义#define #ifndef #endif
目录#define 宏定义一、无参宏定义二、带参宏定义#ifndef 条件编译#define 宏定义在C或C++语言源程序中允许用一个标识符来表示一个字符串,称为“宏”。“define”为宏定义命令。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。优点: (1) 方便程序的修改。这个就不多说了。(2...原创 2020-09-16 12:30:17 · 25231 阅读 · 7 评论 -
【未完成】C++ 内存管理
浅拷贝和深拷贝原创 2020-09-11 21:45:35 · 107 阅读 · 0 评论 -
深拷贝和浅拷贝 默认拷贝构造函数和自定义拷贝构造函数【有代码实例】
目录几种对象的复制(拷贝)情况1.变量对象之间的复制2.指针对象间的复制3.相同类型的类对象间的复制深拷贝和浅拷贝浅拷贝的问题浅拷贝和深拷贝的区别图示:好习惯:自定义拷贝构造函数几种对象的复制(拷贝)情况1.变量对象之间的复制如下:执行完后a,b互不影响。int a=10; int b=a;2.指针对象间的复制只是将其值复制(也就是地址)。拷贝完成后两个指针指向同一个变量,并没有给新指针一个新空间。这时如果通过*p修改a的值,那么对于*q来说原创 2020-09-11 22:19:21 · 822 阅读 · 0 评论 -
利用构造函数对类对象进行初始化及构造函数的重载
对象的初始化类不是实体,而是一种抽象数据类型,并不占存储空间,所以不能在类的声明中对类的数据成员进行初始化。用构造函数实现数据成员的初始化构造函数是一种特殊的成员函数,与其他成员函数不同,不需要用户调用它,在建立对象时自动执行。构造函数的名字与类名相同,没有类型,没有返回值。构造函数一般声明为public#include<iostream> using namespace std;class Box{ public: Box(); //构造函数 v原创 2020-09-11 20:27:10 · 1063 阅读 · 0 评论 -
C++11新特性:for循环遍历容器的新用法
一、普通的for循环#include<iostream>#include<vector>using namespace std;vector<double> a;int main() { a.push_back(1.2); a.push_back(50.56); a.push_back(8.33333); //普通for循环 for (int i=0; i<a.size(); i++)原创 2020-09-11 00:22:39 · 6162 阅读 · 0 评论 -
左值右值,左值引用和右值引用及其用途
C和C++中定义了引用类型(reference type),存在左值引用(lvalue reference)。而在C++11中,新增了右值引用(rvalue reference)这一概念, 虽然个人感觉右值引用用处不大,但在此一并讨论。1.左值和右值首先,我们讨论左值和右值两个概念。左值(lvalue):非临时性对象的表达式。通常来说,可以将程序中所有带名字的变量看做左值。右值(rvalue):相对的,右值标识是临时性对象的表达式,这类对象没有指定的变量名,都是临时计算生成的。考虑以...原创 2020-09-11 01:44:04 · 2652 阅读 · 0 评论 -
C++引用 与 运算符重载
c++中,引用其实还是靠指针实现的 为什么要引入引用呢?c++之父说,最初是为了实现运算符重载方便,下面举个例子例如 c =a +b是可以接受的写法,而c =&a +&b 就不是很方便而且有歧义了那么下面说一下,哪些运算符重载必须用引用呢+=运算符,它本身的意义是「自增,并返回自增后的值」,所以就要返回自己,而不是返回一个自己的拷贝(返回自己的拷贝就成别的值了)还有= 等等还有一个,拷贝构造函数参数一定要是引用不然编译通不过,为什么呢?因为在入参的..原创 2020-09-11 10:22:48 · 599 阅读 · 0 评论 -
C++核心编程【只讲解C++语言特性,需要有C语言基础】
C++核心编程本阶段主要针对C++ 面向对象编程技术做详细讲解,探讨C++中的核心和精髓。1 内存分区模型C++程序在执行时,将内存大方向划分为4个区域代码区:存放函数体的二进制代码,由操作系统进行管理的 全局区:存放全局变量和静态变量以及常量 栈区:由编译器自动分配释放, 存放函数的参数值,局部变量等 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收内存四区意义:不同区域存放的数据,赋予不同的生命周期, 给我们更大的灵活编程1.1 程序运行前C++中在原创 2020-09-11 01:51:37 · 672 阅读 · 1 评论 -
C/C++ 内存分区以及自由存储区和堆的区别
作者:骇客HK出处:https://www.cnblogs.com/ruanraun/p/Heap.htmlC/C++编译的程序占用的内存分区1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数名,局部变量的名等。其操作方式类似于数据结构中的栈。2、堆区(heap)— 由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。3、全局/静态存储区 —全局变量和局部静态变量的存储是放在一块的(在以前的C语言中,..原创 2020-07-26 10:59:02 · 1581 阅读 · 0 评论