![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
t0tott
timj3ly.com
展开
-
2021-03-30
C与C++区别C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制)。C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事务)控制。 所以C与C++的最大区别在于它们的用于解决问题的思想方法不一样。之所以说C++比C更先进,是因为“ 设计这个概念已经被融入到C++之中 ”。下面我们一步一步来分析C++与C的不同:..原创 2021-03-30 14:42:43 · 144 阅读 · 0 评论 -
线程的创建与管理
线程的创建#include <iostream>#include <thread> //头文件using namespace std;void greeting(){ cout << "Hello multithread!"<<endl; return;}int main(){ thread t{greeting}; //列表初始化 t.join(); //确保主线程在子线程退出之后才退出 retur原创 2020-11-13 18:26:36 · 142 阅读 · 0 评论 -
指向类成员的指针 通过偏移得到私有变量
非静态成员#include <iostream>//非静态成员指针using namespace std;class A{public: void NonStaticFunc(int arg){ nonStaticMember = arg; cout<<nonStaticMember<<endl; } int nonStaticMember;};//定义类型 返回类型(类名::指针类型名)(参数列原创 2020-11-12 14:08:19 · 155 阅读 · 0 评论 -
C++11 新特性
1、指针、智能指针(nullptr、shared_ptr、std::weak_ptr)(1)nullptr作用: C++11 引入了 nullptr 关键字,专门用来区分空指针、0原有问题:传统 C++ 会把 NULL、0 视为同一种东西,这取决于编译器如何定义 NULL实现:nullptr 的类型为 nullptr_t,能够隐式的转换为任何指针或成员指针的类型,也能和他们进行相等或者不等的比较。当需要使用 NULL 时候,养成直接使用 nullptr的习惯NULL的定义#ifdef __c原创 2020-11-11 22:23:39 · 566 阅读 · 1 评论 -
vector push_back 时间复杂度
#include <iostream>#include <vector>using namespace std;int main(){ vector<int> vec; int last = 0; for(int i = 0; i <= 1e5; i++){ vec.push_back(1); if(last!=(int)vec.capacity()){ c原创 2020-11-03 07:59:56 · 1321 阅读 · 0 评论 -
ReverseList
#include <iostream>using namespace std;struct ListNode{ int val; struct ListNode *next; ListNode(int x): val(x), next(nullptr){}};ListNode* ReverseList(ListNode *pHead){ if(!pHead) return nullptr; ListNode *fakeEnd = n原创 2020-10-29 19:15:31 · 103 阅读 · 0 评论 -
C++ 常见 内存 错误
野指针野指针:指向不可用内存区域的指针。如果对野指针进行操作,将会使程序发生不可预知的错误,甚至可能直接引起崩溃。野指针不是NULL指针,是指向**“垃圾”**内存的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是野指针是很危险的,也具有很强的掩蔽性,if语句对它不起作用。造成野指针的常见原因有三种:指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针。在Debug模式下,VC++编译器会把未初始化的栈内存上的指针全部填成 0xcccccccc ,当字符串看就是原创 2020-10-22 10:04:09 · 113 阅读 · 0 评论 -
进程、线程、协程 进程间的通信方式 IO多路复用的方式
进程:进程是系统进行资源分配和调度的⼀个独立单位,一个程序在一个数据集中的一次动态执行过程,可以简单理解为“正在执行的程序”。进程一般由程序、数据集、进程控制块三部分组成程序用来描述进程要完成哪些功能以及如何完成;数据集则是程序在执行过程中所需要使用的资源;进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志;进程的局限是创建、撤销和切换的开销比较大线程:线程是进程的⼀个实体, 也叫轻量级进程,是CPU调度和分派的基本单位,原创 2020-10-20 14:10:27 · 593 阅读 · 2 评论 -
函数指针指针函数
指针函数指针函数本质是一个函数,返回值是某一类型指针int* fun(int x,int y);函数指针函数指针是指向函数的指针,本质是指针变量//申明与赋值int (*fun)(int x,int y);fun = &Function;或者int (*fun)(int x,int y);fun = Function;//调用a = (*fun)();a = fun();函数指针数组#include<iostream>using namespace原创 2020-10-20 14:06:18 · 60 阅读 · 0 评论 -
智能指针
unique_ptr左值右值左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式),右值指的则是只能出现在等号右边的变量(或表达式)。需要注意的是,左值是指表达式结束后依然存在的持久对象,而右值是指表达式结束时就不再存在的临时对象。T& 指向的是 lvalue,而 const T& 指向的,却可能是 lvalue 或 rvalue,左值引用&与右值引用&&(右值引用是c++11加上的)。move和forward:需要明确的是,move函数可以是原创 2020-10-20 13:58:05 · 106 阅读 · 0 评论 -
C++类或结构作为map的key值
1.只有重载<的类或者结构才能作为map的key值。string可以作为key值是因为string重载了<2.如果不重载<会提示如下错误:error C2676: 二进制“<”: “const C”不定义该运算符或到预定义运算符可接收的类型的转换...原创 2020-10-20 08:58:12 · 782 阅读 · 0 评论 -
static_cast dynamic_cast
static_cast用法:static_cast < type-id > ( exdivssion )该运算符把exdivssion转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:①用于类层次结构中基类和子类之间指针或引用的转换。 进行上行转换(把子类的指针或引用转换成基类表示)是安全的; 进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。②用于基本数据类型之间的转换,如把int转换成char,把in原创 2020-10-19 15:43:30 · 185 阅读 · 0 评论 -
继承/组合关系时 构造/析构函数执行顺序 虚析构函数存在的意义
继承/组合关系时 构造/析构函数执行顺序#include <iostream>using namespace std;class A{public: A(){ cout<<"A"<<endl; } ~A(){ cout<<"~A"<<endl; } };class B:public A{public: B(){ cout<<"原创 2020-10-19 14:41:43 · 111 阅读 · 0 评论 -
linux df
(base) ➜ ~ df 文件系统 1K-块 已用 可用 已用% 挂载点udev 8137076 0 8137076 0% /devtmpfs 1633052 2128 1630924 1% /run/dev/sda10 199793984 56065704 133509632 30% /tmpfs 8165248 352300原创 2020-10-19 08:37:19 · 269 阅读 · 0 评论 -
linux gdb
gdb启动gdb对C/C++程序的调试,需要在编译前就加上-g选项:$ g++ -g hello.cpp -o hello调试可执行文件:$ gdb <program>program也就是你的执行文件,一般在当前目录下。调试core文件(core是程序非法执行后core dump后产生的文件):$gdb <program> <core dump file>$gdb program core.11127调试服务程序:$ gdb <program原创 2020-10-17 22:20:33 · 112 阅读 · 0 评论 -
重载运算符 不能重载的运算符 单目/双目/三目运算符 重载运算符的方式 友元函数
重载运算符您可以重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。不能重载的运算符写法解释.成员访问运算符., ->成员指针访问运算符::域运算符sizeof长度运算符?条件运算符(三目运算符)#预处理符号单目/双目/三目运算符单目就是这原创 2020-10-17 11:47:13 · 1621 阅读 · 0 评论 -
自旋锁和互斥锁
互斥锁(mutexlock):最常使用于线程同步的锁;标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁;临界区和互斥量都可用来实现此锁,通常情况下锁操作失败会将该线程睡眠等待锁释放时被唤醒。在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。互斥锁是一种简单的加锁的方法来控制对共享资源的访问,互斥锁只有两种状态,即上锁( lock )和解锁( unlock )。原子性:把一个互斥量锁定为一个原子操作,这意味着操作系统(或pthread函数库)保证了如果一原创 2020-10-09 21:24:47 · 368 阅读 · 0 评论 -
手撕快排
#include <iostream>#include <stdio.h>#include <stdlib.h>using namespace std;void quickSort(int arr[], int low, int high){ if(low>=high) return; int key = arr[low]; int left = low; int right = high; while原创 2020-10-09 14:06:14 · 138 阅读 · 0 评论 -
C语言实现继承多态
#include <string.h>#include <stdio.h>struct animal{ char name[20]; void (*speak)();};void Animal(struct animal *this, const char *name, void(*fun)()){ strcpy(this->name, name); this->speak=fun;}struct原创 2020-10-08 21:59:27 · 2814 阅读 · 1 评论 -
哈希函数 一致性哈希
哈希函数1.直接寻址法。取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数)2.数字分析法。分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。原创 2020-10-06 14:13:02 · 421 阅读 · 0 评论 -
拷贝构造函数 浅拷贝遇到的问题 如何用深拷贝解决
使用条件:1.明确表示由一个对象初始化另一个对象2当对象作为函数的实参传递给形参时3当对象作为函数的返回值时#include <iostream>using namespace std;class Person{ private: int m_age; public: Person(int age):m_age(age){ cout<&原创 2020-10-05 21:26:51 · 217 阅读 · 0 评论 -
找到虚函数地址
#include <iostream>using namespace std;class Base{public: virtual void func(){cout<<"Base!"<<endl;} virtual void func2(){cout<<"Base!!"<<endl;}};class Derived:public Base{public: virtual void func原创 2020-10-05 20:04:58 · 201 阅读 · 0 评论 -
C++ 网络编程
TCP与UDP的比较TCP是面向连接的,交互双方的进程各自建立一个流式套接字,服务器需要等待客户端向其提出连接申请。一旦接受客户端申请就立刻返回一个新的套接字描述符。通过该描述符调用数据传输函数与客户端进行数据的收发。UDP是面向无连接的,双方建立的是数据报套接字,服务器和客户端在进行传描数据之前不需要进行连接的申请和建立,可以随时向对方发消息。TCP优点:可靠、稳定缺点:速度慢,效率低、占用系统资源高、易被攻击。适合场景:网络通讯质量要求高(可靠、稳定)UDP优点:速度快,比TCP稍安全原创 2020-09-21 18:26:32 · 548 阅读 · 0 评论 -
C++类的大小 虚析构函数
#include <iostream>using namespace std;class P { int a; //4字节public: virtual ~P() { //父类的虚析构函数 //4字节 std::cout << "P destructor!" << std::endl; }};class Child :public P { int b; //4字节public: virtual ~Ch原创 2020-09-20 16:46:54 · 237 阅读 · 0 评论 -
C++的内存 堆、栈、自由存储区、全局/静态存储区和常量存储区
在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。全局/静态存原创 2020-09-20 15:33:46 · 220 阅读 · 0 评论 -
static关键字 C++
特点:1、static是一个修饰符,用于修饰成员(成员变量,成员函数);2、static修饰的成员被所有的对象共享;3、static优先于对象存在,因为static的成员随着类的加载就已经存在。成员变量和静态变量的区别:生命周期的不同:成员变量随着对象的创建而存在随着对象的回收而释放。静态变量随着类的加载而存在随着类的消失而消失。调用方式不同:成员变量只能被对象调用。静态变量用类名调用。(推荐用类名调用)数据存储位置不同:成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。静原创 2020-09-20 14:48:10 · 72 阅读 · 0 评论 -
进程间的通信方式
管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。管道是一种最基本的IPC(Inter-Process Communication)机制,作用于有血缘关系的进程之间,完成数据传递。调用pipe系统函数即可创建一个管道。有如下特质:其本质是一个伪文件(实为内核缓冲区)由两个文件描述符引用,一个表示读端,一个表示写端。规定数据从管道的写端流入管道,从读端流出。命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无原创 2020-09-17 13:19:42 · 374 阅读 · 0 评论 -
C++ 编译 编译预处理 优化 函数调用约定 汇编 链接
C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的启动代码和用到的库文件进行组织,形成最终生成可执行代码的过程。过程图解如下:从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。编译过程编译过程又可以分成两个阶段:编译和汇编。编译编译是读取源程序(字符流),对之进行词法和语法的分析,将高原创 2020-09-16 12:58:56 · 447 阅读 · 0 评论 -
C++ 类 sizeof 计算大小 虚函数 虚继承 虚基类 虚函数表
文章目录c++类的大小计算关于类/对象大小的计算一.简单情况的计算二.空类的大小三.含有虚函数成员(1)在派生类中不对基类的虚函数进行覆盖,同时派生类中还拥有自己的虚函数在派生类中对基类的虚函数进行覆盖(3)多继承:无虚函数覆盖(4)多重继承,含虚函数覆盖四.虚继承的情况c++类的大小计算c++中类所占的大小计算并没有想象中那么简单,因为涉及到虚函数成员,静态成员,虚继承,多继承以及空类等,不同情况有对应的计算方式,在此对各种情况进行总结。首先要明确一个概念,平时所声明的类只是一种类型定义,它本身是没原创 2020-09-15 16:34:55 · 2552 阅读 · 0 评论