C/C++语言
文章平均质量分 64
qychjj
这个作者很懒,什么都没留下…
展开
-
深入理解C/C++ 关键字const
1 常量函数则包含一个this的常量指针这仅仅是编译器的限制,我们仍然可以绕过编译器的限制,去改变对象的状态,可以强制转换类型 Fred* pFred = (Fred*)this; pFred->intValue = 50;也可以构造另外一个指向同一块内存的指针去修改它的状态。2 常量对象调用非常量函数,编译时会产生语法错误3C++也允许在数据成员...转载 2019-08-12 18:37:41 · 819 阅读 · 0 评论 -
可以省略二维数组的行数,但不能省略列数:定义接受二维数组作为实参的形参时
(1)数组的寻址方式编译器在处理二维数组时,对于array[m][n]的数组,如果要取特定位置的值,比如array[i][j]处的值,编译器的寻址方式是 array + n * i+ j即每行有几个元素(列的数量)。(2)内存的分布二维数组在内存中的地址排列方式是按行排列的,第一行排列完之后再排列第二行,以此类推。因为,当给出数组的列数时,通过列数与行数的关系...转载 2019-04-28 11:07:12 · 9773 阅读 · 2 评论 -
C++虚函数表,虚表指针,内存分布
虚函数表和内存分布那一块转载自:https://blog.twofei.com/496/虚函数效率转载自:https://www.cnblogs.com/rollenholt/articles/2023364.htmlhttps://blog.csdn.net/li1914309758/article/details/79916414前言大家都应该知道C++的精髓是虚函数吧?...转载 2019-04-08 14:58:38 · 756 阅读 · 0 评论 -
c++中的引用到底是什么? const pointer.
How References Work?A reference works as a pointer. A reference is declared as an alias of a variable. It stores the address of the variable, as illustrated:and so a reference variable will has ...翻译 2019-04-02 16:25:42 · 297 阅读 · 0 评论 -
C++ 虚函数表解析
前言C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。关于虚函数的使用方法,我在这里不...转载 2019-04-08 14:25:31 · 169 阅读 · 0 评论 -
RTTI: 观念,机制解析和实现原理
C++的 RTTI 观念和用途https://www.cnblogs.com/findumars/p/6358194.html自从1993年Bjarne Stroustrup 〔注1 〕提出有关C++ 的RTTI功能之建议﹐以及C++的异常处理(exception handling)需要RTTI;最近新推出的C++ 或多或少已提供RTTI。 然而,若不小心使用RTTI,可能会导致软件弹性的...转载 2019-04-08 13:11:03 · 1065 阅读 · 0 评论 -
深入探讨dynamic_cast
dynamic_cast < type-id > ( expression)该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void*;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。dynamic_cast运算符可以在执...转载 2019-04-08 12:46:34 · 173 阅读 · 0 评论 -
new和delete 的用法以及在stl库allocte实现的应用
“new”是C++的一个关键字,同时也是操作符。关于new的话题非常多,因为它确实比较复杂,也非常神秘,下面我将把我了解到的与new有关的内容做一个总结。new的过程当我们使用关键字new在堆上动态创建一个对象时,它实际上做了三件事:获得一块内存空间、调用构造函数、返回正确的指针。当然,如果我们创建的是简单类型的变量,那么第二步会被省略。假如我们定义了如下一个类A:class A{...转载 2019-04-08 06:49:08 · 246 阅读 · 0 评论 -
new/delete 详解
转自:https://blog.csdn.net/hihozoo/article/details/51441521一、new/delete 简介new 和 delete 是 C++ 用于管理 堆内存 的两个运算符,对应于 C 语言中的 malloc 和 free,但是 malloc 和 free 是函数,new 和 delete 是运算符。除此之外,new 在申请内存的同时,还会调用对象的构...转载 2019-04-07 22:32:58 · 1131 阅读 · 0 评论 -
浅谈 C++ 中的 new/delete 和 new[]/delete[]
在 C++ 中,你也许经常使用 new 和 delete 来动态申请和释放内存,但你可曾想过以下问题呢?new 和 delete 是函数吗?new [] 和 delete [] 又是什么?什么时候用它们?你知道 operator new 和 operator delete 吗?为什么 new [] 出来的数组有时可以用 delete 释放有时又不行?…如果你对这些问题都有疑问的话,不...转载 2019-04-07 21:52:34 · 89 阅读 · 0 评论 -
C++变量的存储类别
C++供用户使用的存储空间可以分为三部分,即:(1) 程序区(2) 静态存储区(3) 动态存储区一、动态存储方式与静态存储方式上一节已介绍了变量的一种属性——作用域,作用域是从空间的角度来分析的,分为全局变量和局部变量。变量还有另一种属性——存储期(storage duration,也称生命期)。存储期是指变量在内存中的存在期间。这是从变量值存在的时间角度来分析的。存储期可以...转载 2019-04-07 21:20:42 · 175 阅读 · 0 评论 -
二叉树的遍历:层序遍历,前序遍历,中序遍历,后序遍历
层序遍历:可以采用队列的数据结构。当前节点入队->然后出队,出队时将其左右孩子入队,循环队列进行出队,每次出队将其左右孩子入队。当队列为空时,整棵树层序遍历完毕。...原创 2019-04-11 07:09:25 · 323 阅读 · 0 评论 -
删除数组中某个元素
1) 使用不是该元素的值生存一个新的数组; 时间复杂度o(n),空间复杂度O(n)2)从end开始遍历,当遇到该元素时,将后面的元素前移;时间复杂度o(n*n),空间复杂度O(0)std::vector<int> removeElementFrom(std::vector<int> vec, int elem){ std::vector<int>...原创 2019-04-11 07:05:25 · 441 阅读 · 0 评论 -
c++中const 对象与const 成员函数
为了确保const 对象的数据成员不会被改变,在C++中,const 对象只能调用const 成员函数。如果一个成员函数实际上没有对数据成员作任何形式的修改, 但是它没有被const 关键字限定的,也不能被常量对象调用。常量对象 只能 调常量函数,如果调用了非常量函数,编译时会出错。D:\cppTest\ms\const.cpp [Error] passing 'const Cons...原创 2019-04-10 21:40:31 · 645 阅读 · 0 评论 -
析构函数中抛出的异常
转自:http://se.csai.cn/ExpertEyes/No143.htm析构函数在什么时候被调用执行? 对于C++程序员来说,这个问题比较简单,但是比较爱唠叨的阿愚还是建议应该在此再提一提,也算回顾一下C++的知识,而且这将对后面的讨论和理解由一定帮助。先看一个简单的示例吧!如下:class MyTest_Base{public:virtual ~ MyTe...转载 2010-09-29 16:16:00 · 624 阅读 · 0 评论 -
构造函数中抛出的异常
构造函数中抛出异常时概括性总结 (1) C++中通知对象构造失败的唯一方法那就是在构造函数中抛出异常; (2) 构造函数中抛出异常将导致对象的析构函数不被执行; (3) 当对象发生部分构造时,已经构造完毕的子对象将会逆序地被析构; (4) 哈哈^-^,其是还是那句话, “C++的异常处理不会破坏任何一条面向对象的特性!”转载 2010-09-29 16:14:00 · 597 阅读 · 0 评论 -
内存越界
<br />int a[2];<br />char ar[3];<br />int b[10];<br />b[10]=5;<br />cout<<a[0]<<endl;<br />cout<<b[10]<<endl;<br /><br />这样结果 <br />-8424442<br />5<br /><br /> int a[2];<br />int b[10];<br />b[10]=5;<br />cout<<a[0]<<endl;<br />cout<<b[10]<<endl;<br />这样转载 2010-09-29 16:01:00 · 599 阅读 · 0 评论 -
memcpy的实现
1)注意对输入指针是否为NULL的判断;2)输入和输出的类型 void *3)强制将void* 指针转换为char* 再进行拷贝操作void * memcpy(void *dest,void *src,unsigned count ){ if (dest == NULL || src == NULL) { return NULL; ...转载 2019-07-12 22:11:06 · 413 阅读 · 0 评论 -
C/C++中volatile关键字详解
1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier。这是 BS 在 "The C++ Programming Language" 对 volatile 修饰词的说明:A volatile specifier is a hint to a compiler that a...转载 2019-07-19 08:39:00 · 151 阅读 · 0 评论 -
从编译器角度看本质:C/C++ 中 volatile 关键字详解
目的:建立语言级别的 memory barrier实现:声明的类型变量表示可以被某些编译器未知的因素更改,编译器对访问该变量的代码就不再进行优化,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据,而且读取的数据立刻被保存。实践:1) 中断服务程序中修改的供其它程序检测的变量需要加 volatile; 2) 多任务(多线程)环境下各任务间共享的标志应该加 vol...转载 2019-08-12 17:43:14 · 298 阅读 · 0 评论 -
从编译器角度看本质:C/C++中static的用法全局变量与局部变量
要区分声明周期和作用域。static 局部变量,会存在data段,是其在整个程序执行过程中都存在,并且只有一份。data段是一个全局的内存空间,且变量以保持一份。类的成员变量会在程序运行前初始化,在程序退出后析构。函数局部静态变量,在第一次使用时初始化,在程序退出后释放。使用字面常量初始化一个本地静态 POD 数据(局部静态变量),实际上,这类初始化并不是在程序第一次执行到该变...原创 2019-08-12 16:39:35 · 2785 阅读 · 0 评论 -
内存池与C++实现
https://blog.csdn.net/u010183728/article/details/815313921. 内存池设计1.1 目的在给定的内存buffer上建立内存管理机制,根据用户需求从该buffer上分配内存或者将已经分配的内存释放回buffer中。1.2 要求尽量减少内存碎片,平均效率高于C语言的malloc和free。1.3 设计思路将buff...原创 2019-08-12 13:57:46 · 253 阅读 · 0 评论 -
深入理解C++异常机制
https://www.cnblogs.com/hdk1993/p/4357541.html还是那句开场白:“在恰当的场合使用恰当的特性” 对每个称职的 C++ 程序员来说都是一个基本标准。想要做到这点,就必须要了解语言中每个特性的实现方式及其时空开销。异常处理由于涉及大量底层内容,向来是 C++ 各种高级机制中较难理解和透彻掌握的部分。本文将在尽量少引入底层细节的前提下,讨论 C++ ...转载 2019-08-15 09:54:52 · 2302 阅读 · 0 评论 -
从源代码到程序在内存中运行的全过程解析
作为一个C/C++程序员,搞清楚从编写源代码到程序运行过程中发生的细节是很有必要的。这在之前也是困扰我的一个很大问题,因为最近在忙着找实习,一直没有下定决心来写这篇博客,最近才抽时间写。下面的代码除了明显贴出来的以外,其他的都以下面的代码为例进行说明:int gdata1 = 10;int gdata2 = 0;int gdata3;static int gdata4 = 11;s...转载 2019-08-15 08:55:50 · 1169 阅读 · 0 评论 -
explicit 类构造函数的隐式转换
限制类编译器调用构造函数的隐式转换(单一入参构造函数)我们知道C++是一个类型严格的语言,比如下面一个函数void test_int_proxy(const int_proxy& v) { printf("%d", v.value());}调用者对其传参也应该是一个int_proxy的对象,但是实际情况并非如此。那该如何表述,我个人觉得应该是:编译器对...转载 2019-08-14 17:06:20 · 217 阅读 · 0 评论 -
struct结构体以及字节对齐
structstruct可以将一些相关联的数据打包成一个整体。既然提到了struct那么肯定就避免不了结构体,结构体的内存对齐。1. 什么是结构体?结构体是一系列类型数据的集合这些数据可能描述了一个物体。2. 什么时候会用到结构体?1. 当内置类型无法满足用户需求的时候,没有合适类型的时候,需要封装特定的类型2. 当函数有多个参数时,或者函数的返回值过多的时候,需要封装特定的...转载 2019-08-14 14:05:36 · 937 阅读 · 0 评论 -
sizeof运算符
sizeof运算符sizeof是最冤枉的关键字,它是一个运算符而不是函数!!!1. sizeof是一个关键字(操作符),它的结果类型是size_t.它在头文件中typedef为unsigned int类型。sizeof是算符,而strlen是一个函数2. sizeof可以用类型做参数,strlen只能用char*做参数,而且必须是以’\0’结尾的,sizeof还可以用函数调用(不执行函数...转载 2019-08-14 14:01:15 · 188 阅读 · 0 评论 -
C关键字Register
register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很多很多register 变量,它累死也可能不能全部把这些变量放入寄存器吧,轮也可能轮不到你。一、皇帝身边的小太监----寄存器不知道什么是寄存器?那见过太监没有?没有?其实我也没有。...转载 2019-08-14 13:40:49 · 355 阅读 · 0 评论 -
不用c/c++的标准库,如何实现一个函数
不用库的话,就只能用语言本身来实现需要的函数,在需要时可以使用os提供的api和系统调用。就是模仿标准库的实现。char *strncpy(char *dest, const char *src, size_t count){ char *tmp = dest; while (count) { if ((*tmp = *src) != 0) src++; tmp++...原创 2019-08-06 09:04:15 · 466 阅读 · 0 评论 -
c++如何实现可变参数
除了用可变参数宏外,还可以用initializer_listint initializerSum(initializer_list<int> il) { int sum = 0; for (auto ptr = il.begin(); ptr != il.end(); ptr++) //类似于容器的操作 { sum += *ptr;...原创 2019-08-05 23:02:32 · 5572 阅读 · 0 评论 -
C语言如何实现多参数函数
也就是c语言如何实现变长参数。int printf(const char* format, ...);调用惯例,参数从右到左入栈,具名参数format(称之为lastarg),在进程虚拟内存空间栈的顶端,即小地址端(栈是从大地址到小地址增长的。)使用方式:va_list ap;//定义一个变量, 一个指针。用来指向各个不定参数。类型为 void* 或 char*va_start...原创 2019-08-05 22:28:23 · 7603 阅读 · 0 评论 -
从编译器角度看: lambda表达式
lambda转换为函数对象。现在,Android已经全面转向C++11/14标准了,看代码的话,很多地方变化很大,新标准真的是有点颠覆性的,感觉已经不会C++了。今天有看到lambda表达式,突然想看一下,这货是怎么实现的,如下,写了个例子,分别调用3个lambda表达式: 1 2 3 4 5 6 7 8 9 ...转载 2019-07-26 10:07:18 · 306 阅读 · 0 评论 -
数据类型与右值引用
数据类型:1)标准定义了一些规则,比如占用内存大小,以及对这段内存的解释规则;2)编译器实现这些规则: 分配多大的内存,并对他解释为人类语言。int i=8;i在分配4字节内存空间: 00000000 00000000 00000000 00001000, 并解释为8;如果将这段内存解释为char,则编译器只取一个字节,并解释为相应的字符。(当然有可能不存在这样的字符。)...原创 2019-07-25 13:52:45 · 236 阅读 · 0 评论 -
异常exception与error-code
异常与错误代码的本质区别之一——异常会自动往上层栈传播:一旦异常被抛出,执行流就立即中止,取而代之的是自动的stack-unwinding操作,直到找到一个适当的catch子句。 相较之下,使用error-code的话,要将下层调用发生的错误传播到上层去,就必须手动检查每个调用边界,任何错误,都必须手动转发(返回)给上层,稍有遗漏,就会带着错误的状态继续往下执行,从而在下游不知道...转载 2019-07-19 08:56:34 · 6527 阅读 · 0 评论 -
C++ auto and decltype Explained, by Thomas Becker
http://thbecker.net/articles/auto_and_decltype/section_01.html转载 2019-07-19 08:40:22 · 118 阅读 · 0 评论 -
const类型的成员函数内部如何改变成员变量
<br />转自:http://blog.csdn.net/hsujouchen/archive/2009/08/02/4401304.aspx<br /> <br />通过指针也能实现。<br /> <br /><br /> 在C++中,由const修饰的成员函数的函数体内部,是不能够对成员变量进行修改的。这个特性被用来保证某些成员函数在实现过程中,避免由于程序员大意而对数据进行了错误的修改;同时也说明此成员函数是非修改性的。如只需要返回成员变量的成员函数就被声明为const类型(const的位置在函数定转载 2010-09-29 15:56:00 · 2811 阅读 · 0 评论 -
C++中static成员函数访问非static成员变量
转自: http://hi.baidu.com/hongszh/blog/item/51b01cb31177b3a2d8335a5e.html这几天工作中,看到很多成员函数都用来初始化一些函数指针,当然为了达到这个目的,类的设计者将这类函数都定义为static函数。因为static成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名。在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员。如果静态成员函数中要引用非静态成员时转载 2010-09-29 15:51:00 · 4792 阅读 · 0 评论 -
C++箴言:理解typename的两个含义
转自:http://dev.yesky.com/13/2221013.shtml问题:在下面的 template declarations(模板声明)中 class 和 typename 有什么不同? template class Widget; // uses "class"template class Widget; // uses "typename"转载 2009-11-27 14:13:00 · 435 阅读 · 0 评论 -
C++虚拟机制
(1)如果对象有一个或多个虚函数,编译器将一个隐藏的指针放入对象,该指针称为vptr。这个vptr指向一个全局表,该表称为vtbl。在分发一个虚函数时,运行时系统跟随对象的vptr找到类的vtbl,然后跟随vtbl中适当的项找到方法的代码。(2)对构造函数的调用不可能是虚拟。虚析构函数可以有。(3) 转自:http://blog.chinaunix.net/u/19转载 2009-11-27 13:41:00 · 1647 阅读 · 0 评论 -
数组与指针
待续,,,转载 2009-11-28 18:55:00 · 615 阅读 · 0 评论