
C++
文章平均质量分 67
C++编程知识
信手斩龙
新手 求求多多关照
展开
-
【C++】虚函数表存放在哪里?
1.虚函数表是全局共享的元素,即全局仅有一个.2.虚函数表类似一个数组,类对象中存储vptr指针,指向虚函数表.即虚函数表不是函数,不是程序代码,不肯能存储在代码段.3.虚函数表存储虚函数的地址,即虚函数表的元素是指向类成员函数的指针,而类中虚函数的个数在编译时期可以确定,即虚函数表的大小可以确定,即大小是在编译时期确定的,不必动态分配内存空间存储虚函数表,所以不再堆中.根据以上特征,虚函数表类似于类中静态成员变量.静态成员变量也是全局共享,大小确定.所以我推测虚函数表和静态成员变量一样,存放在全局原创 2021-03-22 22:04:33 · 8578 阅读 · 5 评论 -
【C++】智能指针(史上最详细!)
智能指针为什么要有智能指针?智能指针的使用及原理RAII智能指针的原理auto_ptrunique_ptrshared_ptrshared_ptr的线程安全问题shared_ptr的循环引用循环引用分析为什么要有智能指针?下面我们先分析一下下面这段程序有没有什么内存方面的问题?提示一下:注意分析MergeSort函数中的问题。void MergeSort(int* a, int n) { int* tmp = (int*)malloc(sizeof(int)*n); _MergeSort(a, 0原创 2021-03-14 17:11:56 · 598 阅读 · 0 评论 -
【C++】小知识---i++是不是原子操作?
1.不是原子操作理由:1.i++分为三个阶段:内存到寄存器寄存器自增写回内存这三个阶段中间都可以被中断分离开.举个例子,现有A,B两个线程,初始i=2;A线程完成1,2步后被切换到B线程,在B线程中执行完这3步,再切换回来,此时A寄存器中的i=3写回内存,故最后i=3,而不是正常的4;所以不是原子操作。2.++i呢在多核的机器上,cpu在读取内存i时也会可能发生同时读取到同一值,这就导致两次自增,实际只增加了一次。3.如何实现i++和++i的原子性呢?在多核CPU的复杂内存操作中,处理原创 2021-03-14 16:32:30 · 889 阅读 · 0 评论 -
【C++】四种类型转换
C语言的类型转换void Test (){ int i = 1; // 隐式类型转换 double d = i; printf("%d, %.2f\n" , i, d); int* p = &i; // 显示的强制类型转换 int address = (int) p; printf("%x, %d\n" , p, address);}缺陷: 转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换C++强制类型转换标准C++为了加强类型转换的可视性,原创 2021-03-12 10:27:58 · 238 阅读 · 0 评论 -
【C++】lambda表达式详解
lambda表达式语法lambda表达式书写格式:[捕获列表] (参数列表) mutable -> 返回值类型 { 函数体}lambda表达式各部分说明:[] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。():参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略mutable:默认情况下,lambda函数总是一个const函数,mutable原创 2021-03-11 10:42:59 · 842 阅读 · 0 评论 -
【C++】如何更改const修饰的变量?
一、结论在定义变量的时候加上volatile关键字const volatile int i = 10;但是在我看来,程序员既然用const来修饰变量,那么就不希望其被修改,根据C++标准,对于修改const变量,属于:未定义行为。所以其实不建议这么做的。volatile关键字详解二、分析#include <stdio.h>int main(){ const volatile int i = 10; int* pi = (int*)(&i); *p原创 2021-03-11 09:23:15 · 572 阅读 · 2 评论 -
【C++】关联式容器(map)详解
map概念如果说set对应数学中的“集合”,那么map对应的就是“映射”。map是一种key-value型容器,其中key是关键字,起到索引作用,而value就是其对应的值。与set不同的是它支持下标访问。头文件是特点增加和删除节点对迭代器的影响很小(高效的插入与删除)快速的查找(同set)自动建立key-value的对应,key和value可以是任何你需要的类型可以根据key修改value的记录支持下标[]操作声明map<T1,T2> m其中T1是key类型,T2是v原创 2021-03-10 16:50:59 · 566 阅读 · 0 评论 -
【C++】关联式容器(set)详解
关联式容器 关联容器与序列容器有着根本性的不同,序列容器的元素是按照在容器中的位置来顺序保存和访问的,而关联容器的元素是按关键元素来保存和访问的。关联容器支持高效的关键字查找与访问。两个主要的关联容器类型是map与set。set概念:set里面每个元素只存有一个key,它支持高效的关键字查询操作。set对应数学中的“集合”。特性储存同一类型的数据元素(这点和vector、queue等其他容器相同)每个元素的值都唯一(没有重复的元素)根据元素的值自动排列大小(有序性)无法直接修改原创 2021-03-10 16:42:22 · 573 阅读 · 0 评论 -
【C++】左值右值
左值右值什么是左值?什么是右值?左边的值和右边的值?不不不,这样不全面,先给你一个浅显的解释吧,左值就是可以被赋值的类型,右值就是不可以被赋值的值int a = 2;这个代码中a位于等于运算符左边,数值2位于等于运算符右边,所以a是左值,2是右值。问题来了:那我要是把2放在左边,2是不是就成左值了呢?刚入门的c语言程序员都知道这是不可能的,但是我们还是来写一下,看看编译器报错了什么。int a = 1;2 = a;当编译之后,给出以下报错:[Error] lvalue required a原创 2021-03-09 23:25:52 · 289 阅读 · 0 评论 -
【C语言】strcpy和strncpy的缺陷!
strcpy()函数应该是我们用的比较常用的一个函数,基本功能是将一个字符串拷贝到我指定的内存空间。但是要复制的字符串长度超过这段内存空间的话,结果可能是未知的。strcpy用法这是C语言里面复制字符串的库函数, 函数声明包括在专门处理字符串的头文件<string.h>中:char * strcpy( char * dst, const char * src );这个函数把字符串src复制到一分配好的字符串空间dst中,复制的时候包括标志字符串结尾的空字符一起复制。操作成功,返回dst,原创 2021-03-09 22:53:21 · 575 阅读 · 0 评论 -
【C++】memcpy能比较结构体吗?
比较两个结构体时, 若结构体中含有大量的成员变量, 为了方便, 程序员往往会直接使用memcmp对这两个结构体进行比较, 以避免对每个成员进行分别比较。 这样的代码写起来比较简单, 然而却很可能深藏隐患。 请看下面的示例代码:#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct padding_type { short m1; int m2;}padding_type_t原创 2021-03-09 21:34:48 · 1013 阅读 · 0 评论 -
【C++】memset的坑!
memset函数常被我们用来初始化数组,然而有个坑可能会被我们踩到。静态数组初始化#include <cstring>int main(){ // 静态数组arr int arr[10]; // 将数组所有元素初始化为0 memset(arr,0,sizeof(arr)); // 遍历输出数组元素 for(int i=0;i<10;++i){ cout << arr[i] <原创 2021-03-09 21:33:32 · 411 阅读 · 0 评论 -
【C++】继承详解,菱形继承问题
继承体系概念继承方式赋值兼容规则同名隐藏子类对象的构造过程菱形继承概念是面向对象程序设计是代码可以复用的最重要的手段,它允许程序员在保持原有的类的特性的基础下进行拓展,增加功能。 这样产生的类被称为派生类;class Person{public:void Print(){cout << "name:" << _name << endl; cout << "age:" << _age << endl;}protecte原创 2021-03-04 17:46:51 · 1973 阅读 · 1 评论 -
【C++】迭代器
概念迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。简单来说,迭代器就相当于一个指针,通过这个指针我们可以对一些容器进行遍历。解决了容器底层空间遍历时不连续的问题。分类正向迭代器容器类名::iterator 迭代器名;//正向遍历的思想int array[]={1,2,3,4,5,6,7,8,9,0};for(int i = 0;i<sizeof(array)/siz原创 2021-03-03 23:47:13 · 495 阅读 · 1 评论 -
【C++】容器适配器-----stack、queue、priority_queue
容器适配器概念分类接口底层结构stack模拟实现queue模拟实现priority_queue模拟实现概念 我们可以简单的将容器适配器当做一个接口装置。有的电脑上没有数据转接口,但是有usb接口,这是我们没必要重新买一个电脑,我们可以做一个usb数据转接线。而这根数据转接线就类似于适配器一样。 在C++中,我们已经有了(vector、list、deque等容器)插入、删除、迭代器就电脑usb接口,当我们想要实现栈的操作时,我么没有必要再重新写新的数据结构,只需要将其接口进行重新的封装,相当于做了一原创 2021-03-03 23:41:59 · 329 阅读 · 1 评论 -
【C++】避免重复包含头文件方法
#pragmaonce这个宏有什么作用?为了避免同一个头文件被包含(include)多次,C/C++中有两种宏实现方式:一种是#ifndef方式;另一种是#pragma once方式。在能够支持这两种方式的编译器上,二者并没有太大的区别。但两者仍然有一些细微的区别。两者的使用方式有何区别?方式一:#ifndef SOMEFILE_H#define SOMEFILE_H… … // 声明、定义语句#endif方式二:#pragmaonce… … // 声明、定义语句两者各有何特点原创 2021-02-28 11:43:40 · 314 阅读 · 0 评论 -
【C++】模板详解
模板分类函数模本类模本函数模板template<class T>T Add(T left,T right) return left+right;上述代码只有经过实例化之后才会形成真正的函数,没有进行实例化之前,它只能称为一个函数模板。模板的实例化是指函数模板(或者类模板)生成相应的模板函数(或模板类)的过程。函数模板实例化之后会生成一个真正的函数,但是由于类中的成员函数只有被调用的时候才会初始化,所以类模板经过实例化之后,只是对类进行定义。模板实例化的分类显示实例化原创 2021-02-08 15:42:37 · 166 阅读 · 0 评论 -
【C++】内存泄漏详解
内存泄漏内存泄漏是什么内存泄漏造成的后果内存泄漏的原因内存泄漏的解决方法内存泄漏是什么内存泄漏指的是由于疏忽或错误造成了程序未能释放掉不再使用的内存。内存泄漏造成的后果性能不良,内存会耗尽内存泄漏的原因 对于C++的内存泄漏,总结一句话:就是new出来的内存没有通过delete合理的释放掉!下面总结几种常见的内存泄漏的场景:程序循环new创建出来的对象没有及时的delete掉,导致了内存的泄露#include <iostream>#include <new.h&g原创 2021-02-08 15:02:08 · 775 阅读 · 0 评论 -
【C++】动态内存管理
C++中内存的分布情况内核空间:操作系统相关的代码,用户不能直接访问。栈(由上到下):存储非静态局部变量、函数参数、返回值。内存映射段:静态库,动态库。堆(由下到上):程序运行时动态内存分配,malloc,calloc,realloc,new,new[]申请的空间。数据段:存储全局变量、静态数据。代码段:可执行代码,只读常量。内存函数的区别相同点:都是C语言的库函数,使用时都需要包含头文件返回值都是void*,都需要进行强制类型转换申请成功时返回空间的首地址,失败时返回NULL,所原创 2021-02-08 12:49:29 · 127 阅读 · 0 评论 -
【C++】static关键字详解
全局静态变量在全局变量前加上关键字static,全局变量就定义成一个全局静态变量.静态存储区,在整个程序运行期间一直存在。初始化:未经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化);作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾。局部静态变量在局部变量之前加上关键字static,局部变量就成为一个局部静态变量。内存中的位置:静态存储区初始化:未经初始化的全局静态变量会被自动初始化为0(自动对原创 2021-02-05 15:51:19 · 799 阅读 · 0 评论 -
【C++】Volatile关键字浅析
一、概念 volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统,硬件或者其他线程等。 遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:volatile int vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。volatile int i=10; int原创 2021-02-05 15:44:21 · 198 阅读 · 0 评论 -
【C++】单例模式详解
一、简介单例模式,指的是某一个类,只允许实例出一个对象存在。而实现单例模式有懒汉式和饿汉式。饿汉式指的是在创建类时就初始化好对象,,而懒汉式指的是在需要使用到对象实例时,才进行初始化对象。二、实现方式1、懒汉模式 第一次用到类实例的时候才会去实例化。class singleton{protected: singleton(){}private: static singleton* p;public: static singleton* instance() { if (p ==原创 2021-02-05 15:43:19 · 1775 阅读 · 0 评论 -
【C++】析构函数详解
概念析构函数:与构造函数功能相反,析构函数是完成对象的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作。特性析构函数名是在类名前加上字符 ~无参数无返回值。一个类有且只有一个析构函数。若用户没有显式定义,系统会自动生成默认的析构函数。(不一定会,下面进行解答)1、在下面这个类中,并没有显示定义析构函数,但是编辑器不会生成默认的析构函数,因为在这个类中没有进行资源的管理,所以不需要析构函数。class Date{ Data(int yea原创 2021-01-29 10:13:43 · 857 阅读 · 0 评论 -
【C++】什么情况下编辑器自动生成默认的构造函数?(详解)
首先我们需要明确,在没有显示定义构造函数的时候,编辑器不一定会自动生成默认的构造函数 对c++初学者来说存在一个误区,如果类没有定义任何构造函数,编译器会自动生成默认的构造函数。正确的说法:只有默认构造函数”被需要“的时候编译器才会生成默认构造函数。那么什么时候是编辑器自己想生成的呢?这里我们给出了四个场景 :场景一:含有类对象数据成员,该类对象类型有默认构造函数class A{public: A() { cout << "A()" << endl;原创 2021-01-25 12:27:05 · 3335 阅读 · 0 评论 -
【C++】构造函数不能为哪些情况
构造函数不能为哪些情况1、构造函数不能用const修饰构造函数需要初始化成员变量,如果声明为const函数,则无法修改成员变量;2、构造函数不能是静态成员函数,也就是不能用static修饰静态成员函数是属于整个类的,不是属于对象的,是所有对象共享的资源。没有this指针,不能通过this指针来进行对象的调用。3、构造函数不能为虚函数构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的。而在构造一个对象时,由于对象还未构造成功。编译器无法知道对象 的实际原创 2021-01-25 11:40:51 · 1943 阅读 · 0 评论 -
【C++】必须在初始化列表中初始化的情况
必须用到初始化成员列表的四种情况:初始化一个引用类型的成员变量因为引用在使用的时候必须进行初始化操作#include <iostream>using namespace std; class A{ public: A(int &v) : i(v), p(v), j(v) {} void print_val() { cout << "hello:" << i << " " <<原创 2021-01-25 11:13:06 · 615 阅读 · 0 评论 -
【C++】Debug和Release的区别
debug 和 release 版本有什么不同Debug :调试版本,通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发人员提供 强大的应用程序调试能力。Debug模式下生成两个文件:除了**.exe或者.dll**文件外,还有一个.pdb文件,该文件记录了代码中断点等调试信息。Release:发布版本,不对源代码进行调试,编译时对应用程序的速度进行优化,使得程序在代码大小和运行速度上都是最优的(调试信息可以在单独的PDB文件中生成)。Release模式下转载 2021-01-21 09:53:57 · 1751 阅读 · 1 评论 -
【C++】宏函数和内联函数的区别
宏优点代码复用性提高性能宏缺点不可调试(预编译阶段进行了替换),无类型安全检查可读性差,容易出错。这里附上《c和指针》中的一张表格,总结宏和函数十分到位,我就不多说了#define定义一个比如判断大小,替换常量,很是方便。不过现在也就用下,#define ERROR_POWEROFF -1,#define _CRT_SECURE_NO_WARNINGS 1这样的和编译器有关的东西,不会去写宏函数,宏函数这东西,可读性特别差,在c++中,一般用const/枚举/内联去替代宏。但是原创 2021-01-14 12:36:47 · 240 阅读 · 0 评论 -
【C++】vector中erase用法
在vector数组中我们删除数组经常用的就是erase方法,但是earse的用法一不注意就会出错,今天我就遇到了,所以在这里总结一下,避免大家用错。1、首先介绍一下erase函数的原型:iteratorerase(iterator position);iteratorerase(iterator first, iterator last);我们可以看到erase函数有两种函数原型,一种是给定要删除的位置,另一种是给定删除的区域。2、接下来给出一种常见的错误for(auto iter=vec.原创 2020-12-11 22:18:43 · 79111 阅读 · 13 评论 -
【C++】vector数组的不确定输入
相信大家在做许多OJ题目时,遇到往vector数组中输入不确定行和列的数组,那么该如何处理呢?1、一维数组的不确定输入 这里我们通过cin.get(),这个函数来进行判断,判断输入的是否为回车(也就是换行符),如果输入的是回车,就循环结束,停止输入。int main(){ vector<int> arr; int n=0; while(cin>>n) { arr.push_back(n); if(cin.get原创 2020-12-11 22:19:35 · 3615 阅读 · 1 评论 -
【C++】类和对象(下)
静态成员在类当中,用static修饰的成员变量,称为静态成员。用static修饰的成员函数,称为静态成员函数。静态成员必须在类外进行初始化。静态成员在类外初始化的方法:类名::成员名 ,在初始化时不用加关键字static,因为静态成员的初始化不同构造函数,所以有其返回值,并且静态成员不属于某一个对象,其为同一个类下所有对象的共享。静态成员函数在类当中在函数体之前加上关键字static,静态成员函数,没有隐藏的this指针,因此,其只能访问静态成员变量,不能访问非静态成员变量。非静态成员函数可以调原创 2020-12-22 23:50:39 · 140 阅读 · 0 评论 -
【C++】Vector和List的区别
在学习stl的时候,总是有同学分不清楚Vector和List的使用,在这里我总结一下它们的区别和使用方法。一、底层结构 vector的底层结构是动态顺序表,在内存中是一段连续的空间。 list的底层结构是带头节点的双向循环链表,在内存中不是一段连续的空间。二、支持随机访问 vector支持随机访问,可以利用下标精准定位到一个元素上,访问某个元素的时间复杂度是O(1)。 list不支持随机访问,要想访问list中的某个元素只能是从前向后或从后向前依次遍历,时间复杂度是O(N)。三、插入和删除的原创 2020-12-14 23:15:43 · 7459 阅读 · 5 评论 -
初入编程!
学习编程的自我规划初学c语言,让我对于变成有了一个初始的认识,了解了一些关于编程的知识,也深深知道了自己有多菜...所以在以后的编程学习中要有一个自己的桂规划。首先先定一个小目标———在学习一段时间后,能自己独立动手编一个小游戏的程序。这就是我这一段时间要准球的目标。其次就是自己的打字速度还有待提高,编程是对于打字速度有很高要求的,所以要把自己的打字速度练上去。学习编程其实是一个很漫长,很枯燥...原创 2019-04-01 15:44:19 · 286 阅读 · 1 评论 -
【C++】类与对象(中)
—类的默认成员函数 一个类中什么成员都没有的话,你会认为它是一个空类吗?如果是的话,那么你就错了。其实任何一个类不论是否为空类,都会自动生成下面6个默认成员函数:—构造函数概念 对于一个日期类,我们可以通过以下的方法来给对象设置内容:void set(int year, int month, int day) //构造函数 { _year = year; _month ...原创 2019-08-01 17:46:20 · 186 阅读 · 0 评论 -
【C++】类与对象(上)
- 初识类与对象 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。-类的引用 C语言中,结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。c++中更喜欢用class来代替structstruct Student{void SetS...原创 2019-07-26 17:45:16 · 340 阅读 · 0 评论 -
【C++】基础知识(下)
一、内联函数(1). 概念 以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。 如果在上述函数前增加inline关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。查看方式:在release模式下,查看编译器生成的汇编代码中是否存在call Add在debug模式下,需要对编译器进行...原创 2019-07-24 17:01:35 · 171 阅读 · 0 评论 -
【C++】基础知识(上)
一、C++关键字 以上就是c++的部分关键词,这是c++98版本的关键词,因为版本的原因,与c++11有所出入。我们在写代码的过程中就是将这些关键词组合到一起的过程。二、命名空间 在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染。1. 普...原创 2019-07-24 16:31:00 · 262 阅读 · 0 评论