![](https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C/C++
文章平均质量分 54
ljlstart
这个作者很懒,什么都没留下…
展开
-
C++虚函数的实现机制
1、c++实现多态的方法其实很多人都知道,虚函数在c++中的实现机制就是用虚表和虚指针,但是具体是怎样的呢?从more effecive c++其中一篇文章里面可以知道:是每个类用了一个虚表,每个类的对象用了一个虚指针。具体的用法如下:class A{public: virtual void f(); virtual void g();private转载 2015-10-21 22:51:11 · 287 阅读 · 0 评论 -
inline函数详解
(一)inline函数(摘自C++ Primer的第三版)在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联。 inline int min(int first, int secend) {/****/}; inline 函数对编译器而言必须是可见的,以便它能够在调用点内展开该函数。与非inline函数不同的是,inline函数必须在调用转载 2016-05-06 11:02:37 · 854 阅读 · 0 评论 -
为什么虚构函数不允许抛出异常
C++异常处理模型是为C++语言量身设计的,更进一步的说,它实际上也是为C++语言中面向对象而服务的,C++异常处理模型最大的特点和优势就是对C++中的面向对象提供了最强大的无缝支持。好的,既然如此!那么如果对象在运行期间出现了异常,C++异常处理模型有责任清除那些由于出现异常所导致的已经失效了的对象(也即对象超出了它原来的作用域),并释放对象原来所分配的资源,这就是调用这些对象的析构函数来完成释原创 2015-10-21 22:39:13 · 661 阅读 · 0 评论 -
C/C++的static关键字
static主要有三个作用:(1)局部静态变量(2)外部静态变量/函数(3)静态数据成员/成员函数 前两种C和C++都有,第三种仅在C++中有,下面分别作以下介绍:一、局部静态变量在C/C++中, 局部变量按照存储形式可分为三种auto, static, register。其中register不常用到,下面主要说说auto和static的区别。1. 存储空间分配原创 2016-05-31 10:13:00 · 428 阅读 · 0 评论 -
volitale关键字
volitale关键字是用了防止编译器优化代码的,volitale限定的变量都被指定从内存中读取. int v=10; void func() { int a,b; a=5*v ; b=5*v ; .... } 当编译期间编译器访问这段代码时,在第一次计算5*v的值后,先赋给a,然后直接从寄原创 2016-05-14 16:40:53 · 1304 阅读 · 1 评论 -
C++空类默认有哪些成员函数?
实际上,C++的一个空类并不会默认产生任何成员函数,只有在调用的时候根据编译器的需要生成。 class A{};A a; //编译器会生成默认构造函数,实际上默认构造函数所做的事就是为这个实例添加一个字节的数据class A{};A a1;A a2(a1);//编译器会生成拷贝构造函数,实际上拷贝构造函数所做的事就是把a1中的数据(一个char类型)拷贝到a2中去然而原创 2016-04-29 10:12:43 · 1629 阅读 · 0 评论 -
c++的重载、覆盖和隐藏
转载自:http://blog.csdn.net/wanghuiqi2008/article/details/28419645为了说明这三者的区别,引入函数签名的概念函数签名主要包括1、函数名;2、参数的个数、数据类型和顺序但是注意,函数签名不包括返回值1、重载在同一个类中,或者在顶层函数(与main函数同层)中,如果(1)函数名相同(2)函转载 2016-04-23 00:03:45 · 433 阅读 · 0 评论 -
动态分配内存与静态内存
1) 静态内存分配是在编译时完成的,不需要占用CPU资源;动态分配内存是在运行时完成的,动态内存的分配与释放需要占用CPU资源; 2) 静态内存分配是在栈上分配的,动态内存是堆上分配的; 3) 动态内存分配需要指针或引用数据类型的支持,而静态内存分配不需要; 4) 静态分配内存需要在编译前确定内存块的大小,而动态分配内存不需要编译前确定内存大小,根据运行时环境确定需要的内存块大小,按照转载 2016-06-03 22:23:22 · 1885 阅读 · 0 评论 -
do{}while(0);的妙用
1、辅助定义复杂的宏,避免引用的时候出错:举例来说,假设你需要定义这样一个宏:#define DOSOMETHING()\ foo1();\ foo2();这个宏的本意是,当调用DOSOMETHING()时,函数foo1()和foo2()都会被调用。但是如果你在调用的时候这么写:if(a>0)翻译 2016-06-04 13:10:38 · 468 阅读 · 0 评论 -
C++中的多态
定义 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。 简单地概括为“一个接口,多种方法”。类别 编译时的多态性。 编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。运行时的多态性。 运行时的多态性是以一颗父类的指针或者引用,寻址出继承链中实际的对象,就是直到系原创 2016-06-15 18:02:56 · 395 阅读 · 0 评论 -
关键字static/const的作用
这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:1)在函数体内,一个被声明为静态的变量在这一函数被调用过程中维持其值不变(该变量存放在静态变量区)。2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函转载 2016-06-18 10:17:20 · 504 阅读 · 0 评论 -
private继承与public继承
1 private, public, protected 访问标号的访问范围private:能够访问:1.该类中的函数;2.友元函数。不能访问:1.public继承的子类和private继承子类;2.该类的对象。protected:能够访问:1.该类中的函数;2.public继承的子类和private继承子类;3.友元函数。不能访问:1.该类的对象。public:原创 2016-06-19 12:16:32 · 1001 阅读 · 0 评论 -
Linux下如何检测内存泄漏
Valgrind通常用来成分析程序性能及程序中的内存泄露错误一 Valgrind工具集简绍Valgrind包含下列工具: 1、memcheck:检查程序中的内存问题,如泄漏、越界、非法指针等。 2、callgrind:检测程序代码的运行时间和调用过程,以及分析程序性能。 3、cachegrind:分析CPU的cache命中率、丢失率,用于进行代码优化。原创 2016-04-30 01:17:45 · 2473 阅读 · 0 评论 -
指针和引用的区别
1 指针可以为空,因此使用指针时需要判空操作。而引用一定不会为空。因此从安全性角度考虑引用占优。2 指针可以重新赋值,指向另一个对象。引用只能绑定在最初的对象上。3 引用没有 const,指针有 const,const 的指针不可变,指向的内容可变。4 sizeof(引用)得到的是所指向的变量的大小,而sizeof (指针)得到的是指针本身的大小。总结:当存在“不存原创 2016-05-05 19:43:20 · 8118 阅读 · 0 评论 -
智能指针 weak_ptr
weak_ptr是为了配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手而不是智能指针,因为它不具有普通指针的行为,没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况.用法: weak_ptr被设计为与shared_ptr共同工作,可以从一个shared_ptr或者另一个weak_ptr对象转载 2016-05-04 00:18:56 · 381 阅读 · 0 评论 -
常用的gdb调试命令
一.gdb常用命令:命令描述backtrace(或bt)查看各级函数调用及参数finish连续运行到当前函数返回为止,然后停下来等待命令frame(或f) 帧编号选择栈帧info(或i) locals查看当前栈帧局部变量的值list(或l)列出源代码,接着上次的位置往下列,每次列10行原创 2016-05-01 23:40:18 · 567 阅读 · 0 评论 -
C++中的接口继承和实现继承
很多人认为,C++中是不存在接口继承的,只有Java、C#这类语言才提供了相应的语法支持。但是,如同鲁迅说过的某句名言:世上本没有接口继承,用的人多了,才有了接口继承。C++中依然可以实现接口继承,只是形式上稍有不同罢了。C++中的继承基于一个事实:父类定义的成员函数会一直被子类继承(包括被子类隐藏的部分)。而父类中提供的函数可以有三种:1)普通成员函数 2)普通虚函数 3转载 2015-10-22 00:36:32 · 543 阅读 · 0 评论 -
C++编译器与链接器的工作原理
原文来自:http://blog.sina.com.cn/s/blog_5f8817250100i3oz.html 这里并没不是讨论大学课程中所学的《编译原理》,只是写一些我自己对C++编译器及链接器的工作原理的理解和看法吧,以我的水平,还达不到讲解编译原理(这个很复杂,大学时几乎没学明白)。要明白的几个概念: 1、编译:编译器对源文件进行编译,就是把源文件中的文本形式存在的转载 2016-03-05 10:19:12 · 410 阅读 · 0 评论 -
一个简单实用的C++内存池
1 自定义内存池性能优化的原理如前所述,读者已经了解到"堆"和"栈"的区别。而在编程实践中,不可避免地要大量用到堆上的内存。例如在程序中维护一个链表的数据结构时,每次新增或者删除一个链表的节点,都需要从内存堆上分配或者释放一定的内存;在维护一个动态数组时,如果动态数组的大小不能满足程序需要时,也要在内存堆上分配新的内存空间。1.1 默认内存管理函数的不足利用默认的内存管理函数new/d转载 2016-02-21 16:11:34 · 2553 阅读 · 1 评论 -
为什么基类的析构函数要声明成虚函数
原因:在公有继承中,基类的虚构函数如果不声明成为虚函数,那么销毁派生类时有可能造成资源泄漏class Base{ public: Base( ) { }; ~Base( ) { }; };class Derived :public Base{ public: Derived( ) { }; ~De原创 2015-10-21 22:03:47 · 3540 阅读 · 0 评论 -
extern "C" 的作用
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名,当然前提是C++编译器能够访问C原创 2016-04-09 09:49:48 · 314 阅读 · 0 评论 -
C++中explicit关键字
explicit作用:在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。explicit使用注意事项: * explicit 关键字只能用于类内部的构造函数声明上。 * explicit 关键字作用于单个参数的构造函数。 * 在C++中,expli原创 2015-10-28 23:21:09 · 473 阅读 · 0 评论 -
C++中不能声明为虚函数的有哪些函数
首先明确一点,在编译期间编译器完成了虚表的创建,而虚指针在构造函数期间被初始化。如果构造函数是虚函数,那必然需要通过虚指针来找到虚构造函数的入口地址,但是这个时候我们还没有把虚指针初始化。因此,构造函数不能是虚函数。原创 2016-04-09 20:49:21 · 1560 阅读 · 0 评论 -
C++中的dynamic_cast 操作符
C++提供了四种强制转型的方式,除了dynamic_cast是在运行中被决议,其它三种在编译期即可被决议。联想C++中多态的实现,可以想到既然能在运行中决议,必然和RTTI有关(RTTI 是“Runtime Type Information”的缩写,意思是:运行时类型信息。它提供了运行时确定对象类型的方法),而RTTI存在又存在于虚表当中。所以可以知道由dynamic_cast负责转化的类型在其继原创 2016-04-28 11:35:44 · 313 阅读 · 0 评论 -
C++中如何避免资源泄漏
请看下面一段代码{ object *p = new object(); ... delete p;}如果在执行delete这行代码之前该片段产生异常,程序会在发生异常点停止并产生栈展开,所以不会执行delete语句,造成资源泄漏。解决的方法如下{ share_ptr p(new object()); ...}用智能指针替代普通指针,当发生异常原创 2016-04-16 09:53:37 · 1717 阅读 · 0 评论 -
能不能在构造函数和析构函数中调用虚函数?
可以,但是达不到想要的效果,应该尽可能避免在构造函数和析构函数中调用虚函数。class base{public: base(){ cout<<The size is size()<<endl; }private: virtual size_t size(){ return sizeof(*this); }};class原创 2016-04-16 10:52:22 · 2634 阅读 · 0 评论 -
内联函数和宏定义的区别
使用宏和内联函数都可以节省在函数调用方面所带来的时间和空间开销。二者都采用了空间换时间的方式,在其调用处进行展开:(1) 在预编译时期,宏定义在调用处执行字符串的原样替换。在编译时期,内联函数在调用处展开,同时进行参数类型检查。(2) 内联函数首先是函数,可以像调用普通函数一样调用内联函数。而宏定义往往需要添加很多括号防止歧义,编写更加复杂。(3) 内联函数可以作为某个类的成原创 2016-04-30 00:18:15 · 6909 阅读 · 0 评论 -
C++单例模式
因为在设计或开发中,肯定会有这么一种情况,一个类只能有一个对象被创建,如果有多个对象的话,可能会导致状态的混乱和不一致。这种情况下,单例模式是最恰当的解决办法。它有很多种实现方式,各自的特性不相同,使用的情形也不相同。今天要实现的是常用的三种,分别是饿汉式、懒汉式和多线程式。通过单例模式, 可以做到:1. 确保一个类只有一个实例被建立 2. 提供了一个对对象的全局访问指针 3. 在原创 2016-04-29 11:24:18 · 320 阅读 · 0 评论 -
如何限制对象只能建立在堆上或者栈上
在C++中,类的对象建立分为两种,一种是静态建立,如A a;另一种是动态建立,如A* ptr=new A;这两种方式是有区别的。 静态建立一个类对象,是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。 动态建立类对象,是使用new运算符将对象建立在堆空间转载 2016-06-19 22:58:31 · 503 阅读 · 0 评论