C/C++编程
文章平均质量分 63
mybright_
这个作者很懒,什么都没留下…
展开
-
STL典型使用总结--deque类模板
deque即双端队列,同样采用模板类实现,支持在头部/尾部插入和删除元素:deque.push_back(elem); //在容器尾部添加一个元素deque.push_front(elem); //在容器头部插入一个元素deque.pop_back(elem); //删除容器最后一个元素 deque.pop_front(); //删除容器第一个元素示例:#include...原创 2018-09-24 14:59:48 · 662 阅读 · 0 评论 -
编写简单通用makefile
在Makefile基础中总结了makefile最常用的基础,利用这些知识点,足矣编写通用makefile运用于c/c++项目中。本文基于这样的文件编写makefile: 编写makefile需要实现: (1) 将bank.cpp编译成静态库bank.a/动态库bank.so; (2) 将bank.a和bank.so拷贝/opt/lib目录下; (3) 将bank.h拷贝原创 2017-12-16 21:57:51 · 1330 阅读 · 0 评论 -
C++单例模式(懒汉/饿汉)
单例模式是什么?简单来讲,就是在软件系统中,一个类只允许有一个实例,即只能生成一个对象。怎么实现:类的构造函数声明为private或者protected,以防止被外部生成对象,类的内部保存一个static private的该类类型的指针,类的生成对象操作由类的一个public方法代劳。单例模式又分为懒汉模式和饿汉模式两种,参照网上相关文章,做了下面的总结:1. 饿汉模式//single原创 2017-07-20 19:23:36 · 7438 阅读 · 1 评论 -
组合按键的软件设计(c语言)
需求: 根据用户的四个按键的(上下左右)显示对应的内容,左右键切换显示项目名称,上下键切换切换该项目的具体信息条目。另外有一个无符号整型变量上的每一位用于控制项目的显示与否,该位为1则显示对应项目,反之则不显示该项目。 组合按键采用面向对象的思想,加上数据结构中的双向链表,这样的组合按键需求十分容易实现。 下面是对上述需求的模型化: Linux终端用于显示,键盘上的w、s、a、原创 2017-12-28 18:37:41 · 4727 阅读 · 0 评论 -
c++ this指针与const对象
在 c++的const对象一文中已经介绍了const对象的属性,本文尝试从this指针的角度,再来分析const对象。1. 问题引入 同样的示例,定义一个类,并将其实例化为const对象://1_const_obj.cppclass Obj{private: int pri_dat;public: int get_pri_dat() {原创 2017-11-16 18:38:38 · 1461 阅读 · 0 评论 -
为什么有的操作符重载函数只能是成员函数?
出自于c++ primer 5e的一句话: 赋值(=)、下标([])、调用(())和成员访问箭头(->)运算符必须是成员(函数)。 为什么?对于赋值运算符来说,我们知道一个c++类,程序员如果没有为其定义了赋值操作符重载函数,编译器也会隐式的定义,这样倘若再定义全局赋值运算符重载函数,将会发生二义性。即使编译器允许这样的定义手法,在调用的时候也编译不过:cls& operator=(cls&原创 2017-12-16 15:32:45 · 11406 阅读 · 4 评论 -
Makefile基础
本文总结了makefile的概念及基础语法,不涉及makefire的内置函数。比较简单,是阅读、编写makefile基础。 1、makefile可以理解为是一门新的脚本语言,或者是一种工具,它专门用于编译:项目越庞大,代码文件越多,越能体现makefile的功能之强大。 2、makefile作为一门脚本语言,所以自然是属于解析型语言。解析型语言由解析器去解析成计算机所能识别的二...原创 2017-12-16 16:40:08 · 1258 阅读 · 0 评论 -
派生类覆盖基类的重载的函数
和其他函数一样,类的成员函数不论是否是虚函数都可以被重载(重载的发生需要是在同一作用域)。然而,派生类一旦声明了一个和基类重载函数同名的函数,派生类将会覆盖基类的所有重载函数,也就是说派生类可以覆盖基类重载函数的0个或全部个实例。 如下代码:class Base{public: void func() { printf("Base func()\n"); }; void fun原创 2017-12-24 15:42:34 · 6512 阅读 · 3 评论 -
为什么把c++类的析构函数声明为虚函数?
如题,当一个类为基类的时候,通常其析构函数被声明为虚函数,这是为啥?class BaseCls{public: BaseCls() { printf("BaseCls()\n"); } ~BaseCls() { printf("~BaseCls()\n"); } void test_func() {原创 2017-08-18 23:47:29 · 556 阅读 · 0 评论 -
派生类向基类的自动类型转换
在c++中,派生类向基类的自动类型转换只对指针或引用有效,在派生类对象和基类对象之间不存在这样的转换。将一个派生类对象初始化和赋值给一个基类对象,事实上调用的是基类的拷贝构造函数和赋值操作符重载函数,因为这两个函数的参数是基类类型的const引用,所以还是基于引用的自动类型转换。 派生类向基类的自动类型转换时c++类继承的难点之一,能力有限,先尝试表达自己的看法。转换操作主要发生在: (1)原创 2017-12-23 21:30:11 · 2165 阅读 · 0 评论 -
c++类的不同继承方式
c++类中成员有3种访问属性:public、private和protected,派生类对基类的继承方式同样是这3种。c++类对一个继承而来的成员的访问权限受两个因素影响: (1) 该成员在基类中的访问权限说明符 (2) 派生类的继承方式 需要注意,上述是站在一个派生类的使用者(包括继承该派生类的新派生类)而言的。所站在派生类的实现者而言,他对继承而来的成员的访问权限只是上述的第一点,即原创 2017-12-23 15:53:50 · 7393 阅读 · 0 评论 -
c++有序关联容器中键类型的约束
本文以map为例来解释有序关联容器中键类型的约束。 map是键-值对的集合,可以理解为关联数组: std::map<int, string> map1;map1.insert(make_pair<int, string>(4, "linux"));map1.insert(make_pair<int, string>(2, "c/c++"));map1.insert(make_pair<int原创 2017-12-02 17:29:05 · 470 阅读 · 0 评论 -
c++的const对象
1. const对象c++可以使用const关键字修饰对象,表明该对象为只读对象。只读对象的成员变量不允许被改变,程序中若改变只读对象那么编译阶段编译器将报错。class cls{public: int a; cls() : a(6) {} void print(); void func();};void cls::print(){ func()原创 2017-07-31 12:40:02 · 399 阅读 · 0 评论 -
c++的默认拷贝构造函数,从深度拷贝和浅拷贝说起
1. c++类的默认拷贝构造函数的弊端c++类的中有两个特殊的构造函数,(1)无参构造函数,(2)拷贝构造函数。它们的特殊之处在于: (1)当类中没有定义任何构造函数时,编译器会默认提供一个无参构造函数且其函数体为空; (2)当类中没有定义拷贝构造函数时,编译器会默认提供一个拷贝构造函数,进行成员变量之间的拷贝。(这个拷贝操作是浅拷贝)这里只讲拷贝构造函数。在c语言中,int a = 5; /原创 2017-07-24 19:44:10 · 45321 阅读 · 16 评论 -
c语言和c++的相互调用
在实际项目开发中,c和c++代码的相互调用是常见的,c++能够兼容c语言的编译方式,但是c++编译器g++默认会以c++的方式编译程序,而c程序编译器gcc会默认以c的方式编译它,所以c和c++的相互调用存在一定的技巧。1.c方式编译和c++方式编译一般.cpp文件是采用g++去编译,.c文件是采用gcc编译,然而这不是绝对的。 (1)gcc和g++都可以编译.c文件,也都可以编译.cpp文件。g原创 2017-06-16 15:47:58 · 19575 阅读 · 5 评论 -
gcc和g++
文章转自http://blog.chinaunix.net/uid-23023613-id-88201.html,写得很清晰,下面copy过来的。一、gcc和g++比较编译c/c++代码的时候,有人用gcc,有人用g++,于是各种说法都来了,譬如c代码用gcc,而 c++代码用g++,或者说编译用gcc,链接用g++,一时也不知哪个说法正确,如果再遇上个extern “C”,分歧就更多了,这里我想作转载 2017-06-13 16:36:15 · 569 阅读 · 0 评论 -
c++的引用
1. 变量名在引入引用之前,先回顾下c/c++中的变量名。所谓变量名,实际是一段实际连续存储空间的别名,程序中通过变量来申请并命名存储空间,因此,可以通过变量的名字可以使用存储空间。那么一段连续的存储空间是否只能有一个别名?肯定不是的,那么在c++中就引进引用的概念。2. 引用引用可以看作是一个已定义变量的别名,分为普通引用和特殊引用。2.1 普通引用普通引用其语法方式如下:type& name =原创 2017-06-16 11:28:39 · 428 阅读 · 0 评论 -
c++赋值兼容规则
赋值兼容规则是指在需要父类对象的地方可以使用子类对象来代替: 通过public继承,子类得到了父类除构造/析构函数之外的所有成员,且所有成员的访问属性和父类的完全相同。这样,public继承的子类实际就具备了父类的所有功能,凡是父类能解决的问题,子类都可以解决。 赋值兼容规则是发生在父类和子类之间的: (1) 子类的对象可以赋值给父类对象对象,过程会发生隐式类型转换 (2) 父类类型原创 2017-11-11 09:03:17 · 3599 阅读 · 0 评论 -
c++箭头操作符(->)重载函数
箭头(->)操作符是个二元操作符,其左操作数是类对象的地址或者是重载了箭头运算符的类对象,右操作数是类的成员。箭头操作符重载函数只能是类的成员函数(参考为什么有的操作符重载函数只能是成员函数?)。 箭头运算符的使用方法为:obj->mem; obj->func(); obj为某个类对象的地址,mem和func()分别是该对象的成员变量和成员函数,这样的用法是我们之前学原创 2018-01-06 15:29:14 · 3082 阅读 · 0 评论 -
顺序表(c++实现)
线性表是具有相同类型的n(n>=0)个数据元素的有序(中间不能空位置)有限序列,如: X0, X1, … Xn-1 其中Xi为表项,n为长度。线性表具有如下性质: (1)线性表的首元素X0,只有一个后继。 (2)Xn-1为线性表的最后一个元素,只有一个前驱。 (3)除X0和Xn-1外的其它元素既有前驱又有后继。 (4)支持逐项(下标)访问和顺序存取。原创 2018-01-12 23:37:31 · 756 阅读 · 0 评论 -
数组类(c++实现)
用c++实现数组类以代替原生数组,数组类可以包含数组的长度信息,主动发现访问越界,通过操作符重载还可以实现数组间的赋值赋值操作。类似于之前的线性表,数组类Array为一个抽象模板,数组的存储空间的分配和大小的指定均在子类实现。 数组空间由静态分配所得代码示例://Array.h#ifndef __ARRAY_H__#define __ARRAY_H__#include #inc原创 2018-01-16 22:38:34 · 3637 阅读 · 0 评论 -
STL典型使用--vector类模板
vector是将元素放在一个动态数组中加以管理的容器,vector可以随机存取元素(用[]操作符或at()直接存取),也支持迭代器存取元素;vector在尾部添加或移除元素十分高效,但是在中间或者头部插入/移除元素会比较费时。1. 增加/删除vector内的元素vector采用类模板实现,从而实现了算法和数据类型的分离,因此vector可以存放任何类型的元素(一个vector里的元素只能是一种...原创 2018-09-23 21:32:48 · 1923 阅读 · 0 评论 -
STL典型使用总结 - string类
1. string类的初始化string s1 = &amp;quot;abcd&amp;quot;;string s2(&amp;quot;abcd&amp;quot;);string s3 = s2; //通过调用s3的拷贝构造函数来初始化对象s3string s4 = (3, 'a'); //s4 = &amp;quot;aaa&amp;quot;2. string类的遍历s原创 2018-09-18 00:14:13 · 308 阅读 · 0 评论 -
c++11的一些新特(持续补充)
1. auto关键字在c语言中,auto用于修饰局部变量,也称之为自动变量:void func(){ auto int a; //等价于int a}在c++11中,auto根据用户的初始化内容自动推导其类型:#include &amp;amp;lt;iostream&amp;amp;gt;#include &amp;amp;lt;string&amp;amp;gt;#include &am原创 2018-08-27 23:37:29 · 498 阅读 · 0 评论 -
使用VisualStudio2017开发Linux/c++程序(下)
基于前面的环境及工程构建解决方案:主程序 + 静态库 + 动态库,并在主程序中调用静态库和动态库的函数。(参照文章https://www.cnblogs.com/dongc/p/6599461.html和http://www.mamicode.com/info-detail-1983443.html)一、创建解决方案1、右键解决方案->添加->新建项目 2、 右键stat...原创 2018-05-14 11:48:11 · 4335 阅读 · 3 评论 -
使用VisualStudio2017开发Linux/c++程序(上)
环境 Windows10_x64 CentOS7_64(虚拟机)1、 Windows系统中安装VisualStudio2017 2、 Linux系统中安装gcc、g++和gdbserver 3、 创建Linux/c++项目 3.1创建app_test解决方案 3.2 添加新建项目main 这样vs2017会自动生成main.cpp文件。点击“生成”-...原创 2018-05-11 18:01:46 · 6462 阅读 · 3 评论 -
移植Linux内核链表
Linux内核源码中的链表是一个双向循环链表,该链表的设计具有优秀的封装性和可扩展性。本文将从2.6.39版本内核的内核链表移植到Windows平台的visual studio2010环境中。链表的源码位于内核源码的include/linux/list.h中。移植的步骤如下: (1)去除依赖的头文件 list.h依赖的头文件如下:#include <linux/typ...原创 2018-02-07 16:53:13 · 886 阅读 · 0 评论 -
队列(c++实现)
队列的特点是先进先出,跟栈的c++实现类似,队列的c++实现同样有两种方式: Queue是一个接口类,封装了队列相关的所有操作://Queue.h#ifndef __QUEUE_H__#define __QUEUE_H__#include <exception>template<typename T>class Queue{public:...原创 2018-03-01 14:41:28 · 1327 阅读 · 0 评论 -
栈(c++实现)
栈是一种特殊的线性表, 线性表是具有相同类型的n(n>=0)个数据元素的有序(中间不能空位置)有限序列。 对栈的操作(增/删/读)只能通过栈的一端进行,允许操作的一端称之为栈顶,不允许操作的一端称为栈底。栈的特性为先进后出。c++实现栈,可采用如下的设计思路: Stack是一个接口类,封装了栈的所有操作://Stack.h#ifndef __STACK_H...原创 2018-03-01 10:57:31 · 11388 阅读 · 1 评论 -
gdb调试的常用命令
gcc a.c b.c -o app -g -g:会保留函数名和变量名于app中1、 启动gdb调试功能 (1)gdb app (2)给程序传参:set args xx1 xx22、 查看代码(list/l) (1)查看当前文件:ll 行号l 函数名(2)查看非当前文件:l 文件名:行号l 文件名:函数名(3)设置显示的行数set ...原创 2018-03-15 10:12:44 · 609 阅读 · 0 评论 -
单向链表(c++实现)
在顺序表(c++实现)一文中讲到,顺序表是基于顺序存储结构的数据结构,即用一段地址连续的存储单元依次存储数据元素,与之相对的另一种线性表–链表,它则是基于链式存储结构的数据结构:数据元素除了存储本身的信息之外,还需要存储器直接后继(和前驱)的信息,前者是数据域,后者是指针域。 线性表共有的操作,封装在List类中://List.h#ifndef __LIST_H__#define _原创 2018-01-29 18:38:03 · 1622 阅读 · 0 评论 -
简易内存池的实现
最近在实现一个静态链表,即链表的节点占据的空间并非等到插入时再在堆空间中动态分配,而是在一块我们预先分配好的内存空间(可以在栈也可以在堆上)中找出一块空闲的内存空间来使用,当要销毁给节点时,不是delete掉该空间而是将该空间置为空闲标志。这就是池的思想,内存池、线程池的核心思想也是如此。池的设计考虑到许多内存管理技巧,本文只是记录自己的一些简单的笔记。 定义模板类MemPoolManage原创 2018-01-29 18:09:34 · 504 阅读 · 0 评论 -
offsetof和container_of
背景:在项目中,我将设备的配置信息封装在一个结构体中,并用一个unsigned int的变量上的某些位标志来对应某些配置项,该结构体需要被保存在本地配置文件中,程序启动时需要加载配置文件上记录的该结构体的配置信息,若不存在则将该结构体默认配置信息写入文件。在程序运行期间,若用户改变了某些配置,标志变量对应的标志位被置1,程序在得知发生变化的标志量后就将对应的配置信息更新到配置文件中。 假设原创 2018-02-04 17:00:29 · 528 阅读 · 0 评论 -
实现通用的双向链表(c语言实现)
国庆8天在家阅读李先静大神的书籍,抽空把一些笔记记录下来。从实现一个通用的双向链表开始。1. 构建链表节点 链表节点存值还是存值的地址(指针)?对于通用链表首先要做到能够存放任何数据类型的数据,首先可能会想到的是union,但是数据类型无穷无尽,不可能在union中全部表示。那么可行的办法有两种: (1) 存值typedef struct _DListNode DLis原创 2017-10-16 15:46:08 · 8241 阅读 · 3 评论 -
双向链表(c++实现)
单向链表的缺点:逆序访问单向链表中的数据元素,效率低下。 若从头节点开始依次访问单向链表的元素,可使用m_current游标,但是逆序访问,只能通过下面代码实现访问:int main(void){ LinkListint> ll; for (int i = 0; i 6; ++i) //O(n) { ll.insert(0, i); }原创 2018-02-02 18:14:36 · 4118 阅读 · 0 评论 -
循环单向链表(c++实现)
在单向链表(c++实现)中,链表的最后一个节点的nex指针指向NULL,而所谓的循环单向链表即是指链表的最后一个节点的next指针指向首节点(注意不是头节点,头节点是方便链表操作而存在的结构体变量)。循环链表是一种特殊的单向链表,因此软件设计上,循环链表可继承自单向链表。 循环单向链表的实现难点在于: (1)插入数据的位置为0时,头节点和尾节点的next指针均指向新节点; (2)原创 2018-02-02 18:06:17 · 3836 阅读 · 0 评论 -
程序中数据存放的位置
基本上程序员在开始接触Linux编程时就大抵就都听过代码段、数据段等等概念,它们是各种数据存放的位置。通过objdump -h命令可以查看一个.o文件(已编译成二进制文件但未链接)的各个段:1. 代码段(.txt) .txt段存放代码(如函数)与部分整数常量,.txt段的数据可以被执行2. 数据段(.data) .data用于存放初始化过的全局变量。若全局变量值为0原创 2017-10-16 17:30:50 · 4053 阅读 · 0 评论 -
实现智能指针
c/c++中内存的动态分配的结果是一个指针,该指针指向该片堆内存空间。c/c++中并没有垃圾回收机制,而用户使用完该堆空间后又可能忘记释放该片堆内存空间,这就造成内存泄漏。一个行之有效的解决办法就是采用智能指针代替原始指针,弥补原生指针无法控制所指堆空间的生命期的空缺。 在c++11标准中有多个智能指针,其中包括共享指针shared_ptr和独占指针unique_ptr。本文将实现Share原创 2018-02-02 12:47:22 · 436 阅读 · 0 评论 -
数据结构概念解析
1. 什么是数据结构 计算机软件是为了解决现实生活中的问题而存在的,生活中的不同个体体现在软件中即是“数据”。生活中的不同个体间势必存在某些联系,所以在软件设计中需要用某种逻辑来表现这些关系,这就是数据结构。 计算机的“数据”有3个重要概念: 数据元素:组成“数据”的基本单元 数据项:一个数据元素由若干个数据组成 数据对象:性质相同的数据元素的集合 听起来比较抽象,可以用“人原创 2017-10-14 16:19:32 · 392 阅读 · 0 评论 -
当c++中的联合体遇到类的构造函数
在学习Qt的QVariant时,Qt Create的说明手册中说道:Because C++ forbids unions from including types that have non-default constructors or destructors, most interesting Qt classes cannot be used in unions. 大概意思是:因为c++禁原创 2017-09-22 10:29:33 · 4064 阅读 · 2 评论