C/C++
文章平均质量分 87
晚风_清扬
路漫漫
展开
-
C/C++代码:递归遍历当前文件夹下的文件和子文件夹
#include <iostream>#include <io.h>#include <string>using namespace std;void listFiles(const char * dir,int tab);int main(){ string dir; cout << "Enter a directory (e...原创 2018-09-01 14:06:33 · 5394 阅读 · 0 评论 -
C++继承(单继承、多继承、菱形继承)内存模型的深入研究
继承的概念:继承机制:可以利用已有的数据类型来定义新的数据类型,所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。OOP强调软件的可重用性(software reuseablility).C++提供类的继承机制,解决了软件中代码重用的问题:代码复用继承方式继承方式 基类的访问限定 派生类的访问限定 外部的访问限定 Public: public ...原创 2018-02-27 00:28:56 · 2836 阅读 · 1 评论 -
C++中string和int的相互转化
int转化成stringstring s = to_string(100);int 转化成char*char s[128] = {0};sprintf(s,"%d",100);char *转化成intchar * s = "1256" int a = atoi(s);sscanf(s,"%d",&a); string 转化成int#include...原创 2018-02-02 14:16:16 · 401 阅读 · 0 评论 -
自己实现一个带引用计数的智能指针,根据源码
//存储资源引用计数的表,使用单例模式因为模板在类型推导的时候//会因为类型的不同从而产生不同的表,对于引用计数来说会产生错误//因为这两张表应该在同一张表中,在调试中遇到的这个问题class ResTable{public: typedef map::iterator iterator; /* 快加载:没调用getInstance函数,对象实例就生成了 慢加载:第一次调用ge原创 2018-01-22 21:55:40 · 429 阅读 · 0 评论 -
C++的四种类型强转
C++的四种类型强转,const_cast 用于去掉const属性static_cast编译器角度去进行类型的强转这样会更安全。编译器觉得那些类型转换可以,就允许转换,认为不安全的则拒绝转换。reinterpret_cast和C的强转风格一样,啥都可以转,不做任何的类型安全检查如果用于多态中:开发者保证基类的指针指向派生类的对象地址,然后通过该转原创 2018-01-21 21:39:02 · 555 阅读 · 0 评论 -
模板学习笔记
/*模板和内联是一样的,都必须放在头文件中。内联需要在调用的地方进行内联展开,也必须看到定义。因为模板需要在调用的地方进行实例化产生对应的模板函数的代码,不调用则不编译如果在实例化的过程中找不到定义只能看到申明的话,只生成模板函数实例化的声明无法完成定义的实例化解决方法::使用模板的显示实例化,指定需要实例化的模板函数指定类型,但是麻烦静多态:函数重载,模板实例化。在编译的原创 2017-12-09 11:19:16 · 218 阅读 · 0 评论 -
运算符重载和模板的使用
#includeusing namespace std;templateclass CComplex // CComplex{public: CComplex(T r = T(), T i = T()) :mreal(r), mimage(i){} //前置和后置++运算符的重载 CComplex& operator++() { ++mreal; ++mimag原创 2017-12-09 10:55:49 · 453 阅读 · 0 评论 -
运算符重载和普通类
#includeusing namespace std;class CComplex{public:CComplex(int r = 10, int i = 10) :mreal(r), mimage(i){ ; }CComplex& operator=(const CComplex&obj) { return *this; }CComplex operator+(const原创 2017-12-09 10:45:12 · 234 阅读 · 0 评论 -
根据源码自己实现一个容器的空间适配器
//自己实现的容器的空间配置器//主要目的是将对象的内存分配、对象的构造、对象的析构、对象内存的释放等//等操作分离考来templateclass myallocator{public: //allocate : 开辟内存的 T* allocate(size_t size) { //从内存池分配内存 ngx的内存池 return (T*)operato原创 2017-12-09 10:37:16 · 183 阅读 · 0 评论 -
C++多态、虚函数表、动态链接,虚函数指针,RTTI
多态多态的概念:基类指针指向派生类的地址,通过实现派生类的重写函数实现同一个函数接口不同的功能。多态性在Object Pascal和C++中都是通过虚函数(Virtual Function)实现的,因为通过父类的指针去调用不同的子类指针对父类虚函数的重写方法实现多态,同样的接口函数可以实现不同的功能。虚函数通过动态绑定实现、动态绑定通过vfptr(虚函数指针)和vftable(虚函数表)来实现的联...原创 2018-02-27 16:36:04 · 1093 阅读 · 3 评论 -
#pragma once 与 #ifndef 解析
原文地址:http://blog.csdn.net/slimfox/article/details/1565950为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式。在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。 方式一: #ifndef __SOMEFILE_H__ ...转载 2018-02-16 13:21:52 · 173 阅读 · 0 评论 -
顺序循环队列C++实现2倍扩容版本
class CircleQueue{public: CircleQueue(int size = 20); ~CircleQueue(); CircleQueue(const CircleQueue &src); void operator =(const CircleQueue &src); void push(int val); void pop(); int...原创 2018-02-16 15:25:41 · 1484 阅读 · 2 评论 -
面试题:strcpy考虑内存重叠
面试时遇到些strcpy()函数,本来挺简单的,但是面试官的一番描述让我有些不知道怎么下手我当时觉得考虑内存重叠问题就可以了,但是他说的不是我理解的那样,然后就一直卡在那了,不过面试官很有耐心,我自己都开始嫌弃自己的理解能力了。不过面试官还是耐心的给我解释具体的情况。。唉,很可惜,还是自己学得不够,要深刻反思。接下来实现考虑内存重叠的strcpy的函数注意事项:1. 判断输入参数的合法性。2. 要...原创 2018-03-20 12:14:19 · 2122 阅读 · 0 评论 -
vector扩容面试题总结
vector底层数据结构是一个动态数组。 默认构造的方式是0, 之后插入按照1 2 4 8 16 二倍扩容。注(GCC是二倍扩容,VS13是1.5倍扩容。原因可以考虑内存碎片和伙伴系统,内存的浪费)。扩容后是一片新的内存,需要把旧内存空间中的所有元素都拷贝进新内存空间中去,之后再在新内存空间中的原数据的后面继续进行插入构造新元素,并且同时释放旧内存空间,并且,由于vector 空...原创 2018-03-12 10:59:06 · 4181 阅读 · 0 评论 -
汇编代码分析----函数的调用堆栈过程(进程内核栈的切换过程)
当栈中保存函数调用所需要的维护信息,我们称之为堆栈帧。堆栈帧一般包括以下几个方面的内容:函数的返回地址和参数临时变量函数调用的上下文信息一个函数的堆栈帧用ebp和esp两个寄存器划定范围ebp寄存器始终指向当前函数栈帧的栈底。esp寄存器始终指向当前函数栈帧的栈顶。堆栈帧是从高地址向低地址增长的。具体的函数调用过程让我用一个简单的程序并结合画图讲解以增加自己对其过程的深入理解。int sum(in...原创 2017-10-15 19:48:26 · 1276 阅读 · 0 评论 -
LINUX内核研究----C/C++内存管理glibc运行库底层ptmalloc内存管理源码分析总结
基础知识:32位进程的虚拟地址空间64位进程的虚拟地址空间应用程序的堆栈从最高地址处开始向下生长,.bss段与.Stack之间的空间是空闲的,空闲空间被分成两部分,一部分为heap,一部分为mmap映射区域。Heap和mmap区域都可以供用户自由使用,但是它在刚开始的时候并没有映射到内存空间内,是不可访问的。在向内核请求分配该空间之前,对这个空间的访问会导致segmentationfault(段错...原创 2018-02-24 20:43:46 · 707 阅读 · 0 评论 -
LINUX内核研究----IO复用函数epoll内核源代码深度剖析
select和poll的效率瓶颈有两个 1、每次调用这些函数的时候都需要将监控的fd和需要监控的事件从用户空间拷贝到内核空间,非常影响效率。而epoll就是自己保存用户空间拷入的fd和需要监控的事件,只需在调用epoll_ctl的时候就把所有的fd和需要监控的事件只进行一次从用户空间到内核空间的拷贝。 2、select和poll在内核中都是采用线性轮询的方式检查整个数组(poll是链表...原创 2018-02-25 21:45:42 · 1573 阅读 · 0 评论 -
C/C++语言中怎么使用extern c
C++为了和C兼容,C++使用extern “C”关键字C++编译器将在extern “C”的大括号的内部的代码当做C语言编译处理,这样C++的名称修饰规则将不会起作用。主要原因是:作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:void foo( int x,int y );该函数被C编译器编译后在...原创 2017-10-10 20:47:46 · 255 阅读 · 0 评论 -
对目标文件(可重定位文件)ELF文件结构的个人研究及理解
目标文件的格式:现在PC平台流行的可执行文件格式主要是windows下的PE(.exe)和linux(.out)下的ELF。目标文件就是源代码经过编译链接后但未进行链接的那些中间文件,也叫可重定位文件:windows下的(.obj)和linux下的(.o)文件,他们跟可执行文件的格式几乎是一样的。不光是目标文件按照可执行文件格式存储动态链接库(windows下的.dll、linux下的.so)静态...原创 2017-10-09 22:21:25 · 601 阅读 · 0 评论 -
STL的堆算法实现优先级队列
#include<iostream>#include<vector>#include<algorithm>using namespace std;/*利用STL堆算法实现的堆结构,优先级队列的底层就是大小堆*/class heap{public: heap(int *a = NULL, int n = 0) :vc(a, a + n), _s...原创 2018-02-16 20:05:24 · 301 阅读 · 0 评论 -
类成员函数和函数返回值的结合使用探究
/*类型是否匹配,&不修饰类型,const修饰指针的时候参与类型返回是值的话,内置类型的话就是寄存器带出都是常量数字不能取地址,没有内存。返回的是指针的话都是一个立即数常量数字,需要用常引用返回的是引用的话,返回return后面的表达式的地址,可以用指针和引用接收都是可以*/#include#includeusing namespace std;class Test{publ原创 2017-11-20 13:43:01 · 1256 阅读 · 0 评论 -
const 和一级指针、二级指针、引用的结合使用总结
#include#includeusing namespace std;int main(int argc, char* argv[]){ //const int a = 10; // C++中是真正的常量,C++是强类型语言 但是在C语言中是常变量,可以通过地址修改常变量的值 //int b = a;//值传递,正确!a和b没有联系,各自独立的地址,只是值一样 //int原创 2017-11-20 12:09:46 · 726 阅读 · 0 评论 -
常引用的编译器实现原理
int &a = 100;//不能引用右值,因为右值没有内存。错误的表达式 //改正方法是,使用const int & c = 10; //原因是在编译器中,会产生临时量保存10 //然后对临时量地址进行引用 /* 汇编代码: const int& a = 100; 00BA5D98 mov dword ptr [ebp-18h],64原创 2017-11-20 12:06:24 · 280 阅读 · 0 评论 -
单例模式
单例模式:一个类只能生成一个对象快加载的单例模式:1、私有化构造函数2、提供对象实例的接口3、创建私有化的单例对象快加载的单例模式:class Singleton{public: static Singleton* getInstance()//2.该公有接口专门返回对象实例 { return &sobj; }private: Singleton();//1.私有化构造函...原创 2017-11-10 16:25:42 · 212 阅读 · 0 评论 -
编译器在什么情况下无法产生类的四个默认函数
当成员变量有常量、引用的时候,不能生产拷贝构造函数和默认的构造函数。因为这两个是C++唯一必须赋初始值和不能被更改的成员变量。编译器默认拷贝构造会对引用进行更改,自己写的拷贝构造函数是进行初始化原创 2017-11-03 15:18:27 · 456 阅读 · 0 评论 -
i++和++i的区别和实现的原理探究
int main(){ int i = 0; i++; ++i; system("pause"); return 0;}首先看一段简单的程序,通过反汇编直接探究i++和++i的实现原理原创 2017-10-22 20:10:02 · 3604 阅读 · 1 评论 -
指针和数组的区别
在一个项目中定义两个文件//a.cppint a[3] = { 1, 2, 3 };//b.cpp#includeextern int *a;//引用a.cpp的数组名a,但是不把它当数组而是当成指针void main(){ printf("%d\n", a); printf("%d\n", a + 1); printf("%d\n", *a); getchar();原创 2017-10-22 21:59:46 · 165 阅读 · 0 评论 -
汇编角度看指针和引用的区别
一、定义上来看:引用是变量的别名,指针是指向变量的地址。引用不可以为空但是指针可以为空,所以引用必须在定义的时候必须初始化并且初始化后不能被改变引用的对象,但是指针可以该变自己的指向。引用必须引用有内存地址的量,如果是引用常量的话,必须使用常引用。(常引用的实现方法是编译器为常量开辟一个临时量的内存空间进行引用)对引用和指针分别用SIZEOF求大小的话,引用的结果是所指向对像的大小,但是指针则永远...原创 2017-10-20 16:48:51 · 967 阅读 · 0 评论 -
强符号和弱符号
在编程的过程中经常会遇到一种符号重定义的情况。比如在多个目标文件中含有名字相同的全局变量的定义,那么在链接时会出现符号重定义的错误,我们将这种符号称为强符号。相对来说我们也可以定义一种叫做弱符号的概念,C/C++编译器来说默认函数和初始化了的全局变量为强符号,而未初始化的全局变量为弱符号。针对强弱符号的定义,链接器会按照下列的规则进行处理强弱符号的选择:1、 不允许强符号多次定义,如果有原创 2017-10-10 21:23:25 · 1446 阅读 · 0 评论 -
编程判断是C源文件还是C++源文件
C+编译器会在编译C++源程序的时候自动生成一个宏:__cplusplus 可以通过这个宏来判断是C源文件还是C++源文件代码如下#includevoid main(){#ifdef __cplusplus printf("c++");#else printf("c");#endif}原创 2017-10-10 20:42:59 · 1011 阅读 · 0 评论 -
C/C++的函数调用约定
在函数调用时,计算机用栈来维持函数调用的上下文信息,我们称之为栈帧。Linux和windows下栈的大小都是预先确定的,大小为1M,这个大小是可以更改。调用函数前,首先把主调函数下一指令的地址入栈,然后函数的参数入栈。调用函数前有两个比较重要的问题要解决:1、参数入栈的顺序?2、谁来清理栈内存?函数调用约定则解决了这两个问题:_cdecl C调用方式,是C语言缺省原创 2017-09-27 21:40:35 · 341 阅读 · 0 评论 -
函数默认参数
C++中允许函数在定义或者声明时,设置函数的默认参数,调用时如果不指定参数的具体值则按照默认参数调用。但是需要注意一下几点:1、必须从右向左添加默认值,也就是默认值参数的右边参数都必须是默认值Void fun(int a , int b , int c =10);//正确Void fun(int a , int b = 10, int c );//不予讯原创 2017-11-02 15:04:12 · 465 阅读 · 0 评论 -
函数重载
在C++中允许函数有相同的名字,不同的参数类型,这是一中典型的静多态。实现函数重载的条件;1、 在同一作用域下,不同作用域下同名函数谈不上函数重载2、 参数列表不同:参数个数、参数类型、参数顺序都可以确定是否可以重载3、 不能依据返回值来确定函数是否能重载4、 当const 和函数的参数结合时是否可以决定重载?一个结论:看能不能通过修改形参,来影响实参的值?如果一个函数原创 2017-11-02 15:49:40 · 219 阅读 · 0 评论 -
内联函数、普通函数、宏定义
对于一个频繁使用的短小函数,c用宏定义,c++用inline实现。一、宏定义和内联函数的区别1、宏定义只是普通的文本替换,宏定义是没有类型检查的,无论对还是错都是直接替换。所以宏替换容易出错,直接替换会产生符号的优先级的问题会一些意想不到的结果。 内联函数在编译的时候会进行类型的检查,内联函数满足函数的性质,比如有返回值、参数列表等。相对宏替换来说不仅提高了效率还原创 2017-10-18 16:26:05 · 361 阅读 · 0 评论 -
用typeid().name()获取类型名
#include#include//需要添加的头文件using namespace std;void main(){ //typeid().name()可以返回变量、函数、类的数据类型名,功能是相当强大的 //注意:对非引用类型,typeid().name()是在编译时期识别的,只有引用类型才会在运行时识别 const int a = 10; cout << typeid(&a)原创 2017-11-20 11:22:54 · 4296 阅读 · 3 评论 -
函数返回对象和对象的生命周期的结合
函数在返回自定义类型时,我们知道主调函数会为返回值开辟一个临时内存来存储这个返回值对象,但是在返回对象的时候也有一些特殊的情况,Main函数不会为返回的对象开辟内存。虽然在写代码的时候不会这样写,但是需要学会相关的分析,解决一些不能理解的现象:为了便于复习,写成博客。有兴趣的同行可以对以下图片无损放大查看:原创 2017-11-06 22:20:20 · 1661 阅读 · 0 评论 -
类中的三种函数(普通成员函数、静态成员函数、COSNT成员函数)总结
普通成员方法:1、属于类的作用域2、可以访问当前类对象的私有成员THIS3、使用时必须使用对象来调用,在最后传入的参数中有THIS指针,指向对象本身的地址4、普通对象可以调用CONST常方法和静态方法。静态成员变量:1、需要在类外初始化,且只能初始化一次2、该成员属于类的而不是对象的,所有对象共享的。static修饰的静态方法:1、属于类的作用域2、没有原创 2017-11-10 15:53:46 · 1307 阅读 · 0 评论 -
OOP思想
面向对象思想:程序 = 对象 + 对象 + 对象 + 。。。+消息通信面向过程思想:程序 = 算法(函数) + 数据;面向对象的特征:抽象:用类来抽象模拟表示世界中的各类具体事物:属性 + 行为。 成员变量和成员方法 类只是描述一个实体的抽象数据类型。 封装/隐藏;访问限定符(public\protect\private)继承、多态、有什么区别?类和类之间常用的原创 2017-11-03 16:09:02 · 491 阅读 · 0 评论 -
对象的生存周期探究
#include#includeusing namespace std;class Test{public: Test(int a = 5, int b = 5) :ma(a), mb(b) { cout << this << " Test("<<a<<" "<<b<<")" << endl; } ~Test() { cout << this << "~Test(原创 2017-11-03 16:06:24 · 210 阅读 · 0 评论 -
构造函数初始化列表
1、 初始化列表在构造函数之前执行,这个时候是进行初始化操作。而在构造函数体内是进行赋值操作。分清赋值和初始化的不同2、 对于内置类型写到初始化列表还是写到构造函数函数体都没有区别,但是对类成员对象的时候必须写到初始化列表。因为必须对成员对象进行初始化操作。3、成员初始化列表没有规定执行顺序而是按照成员变量定义的顺序进行初始化4、类中的const常量和引用变原创 2017-11-03 14:59:22 · 398 阅读 · 0 评论