随笔分类 -  C++

上一页 1 2 3 4 5 6 7 下一页
理解C++ static
摘要:1、为什么设计static?考虑下面的需求: 在程序运行过程中,在一个范围内,有一个对象大家共享,而且可以多次使用,状态能够保持,对象的生命周期一直持续到程序运行结束。2、静态对象要分配在全局数据区,程序运行期间,不能释放,一直到程序终止。3、静态对象的生命周期是程序的整个运行过程。但是可以限定静态对象的作用域,根据作用域的大小,可分为静态局部对象,静态全局对象。静态局部对象是指方法内的静态对象,静态全局对象是指编译单元里的静态对象。(注意:生命周期是时间概念,作用域是空间概念)4、静态对象只能初始化一次。严格来讲,任何对象都只能初始化一次,而且是在定义的时候。后面再想修改对象的值,只能通过. 阅读全文
posted @ 2013-11-07 20:30 Andy Niu 阅读(1326) 评论(0) 推荐(0)
程序地址空间
摘要:1、程序地址空间,从下到上(下面是低地址,上面是高地址)分别为全局数据区,堆,栈,堆往上增长,栈往下增长。2、程序运行后,还存在一个代码区,代码区放的是可执行代码,索引了一个个的方法,可认为是数据加工厂。3、全局数据区存放:全局数据,文本常量,具名常量,静态全局量,静态局部量。 阅读全文
posted @ 2013-11-06 21:06 Andy Niu 阅读(470) 评论(0) 推荐(0)
【S4】使用empty()而不是判断size()是否为0
摘要:1、二者的作用是一样的,结果也是等价的。就是判断集合是否为空。2、二者是等价的,为什么强调使用empty,因为empty效率更高。3、在STL中,对于一般的集合,empty和size都是常数时间。但是对于list,empty是常数时间,size是线性时间;考虑为什么? 考虑增删操作,对于一般的集合,增删是线性时间,因为涉及到元素的移动,增删的同时也就更新了元素个数。但是对list增删,是常数时间,不会更新节点个数。 因此,对于一般的集合,size是实时更新的,empty与size可认为是等价的。但是对于list:对于empty,只需要检查head是否为end就可以了,为常数时间。对于siz.. 阅读全文
posted @ 2013-11-06 20:42 Andy Niu 阅读(556) 评论(0) 推荐(0)
获取集合的方法
摘要:考虑下面的需求,从配置文件中,读取一些数据,这些数据放到一个集合中,获取集合,使用方法A,完成任务。该怎么做?1、首先明确一点,坚决不能让A返回引用。2、方法A在栈上创建集合,返回集合。不存在内存泄漏的问题,但是要付出copy代价。3、方法A在堆上创建集合,返回集合的指针,copy代价很低,但是会存在内存泄漏的问题。4、主调方法创建一个集合,把集合的引用传递给被调方法A,A修改集合的内容。这个不直观,客户要一些东西,方法A要求客户准备一个容器,A在容器中填充内容。5、采用哪种方法,要看具体的使用场景,如果集合内容很小,copy代价小,就不要用指针,否者用指针。6、还要考虑另外一种情况,返回的集 阅读全文
posted @ 2013-11-06 20:21 Andy Niu 阅读(669) 评论(0) 推荐(0)
VS 统计代码行数
摘要:使用正则表达式: ^:b*[^:b#/]+.*$简单说明如下:^:行头$:行尾+:一个或多个*:0个或多个:b:表示空白,匹配空格或者制表符# 表示后面是include,/表示注释^:b*[^:b#/]+.*$ 查找一些行,行的开头有多个空白,后面不是空白,不是#,不是/,这个正则表达式不能剔除 /****/中的后面两行。 阅读全文
posted @ 2013-11-06 19:59 Andy Niu 阅读(1148) 评论(0) 推荐(0)
指针的删除动作
摘要:指针的删除动作,如果是安全的操作,必须保证:1、此指针由new返回,说明对象分配在堆上,而不是在栈上,或者其他位置。2、指向的对象确实不再使用,如果对象还在使用,销毁了对象,指针成为野指针,指向垃圾。 阅读全文
posted @ 2013-11-06 13:50 Andy Niu 阅读(398) 评论(0) 推荐(0)
C++ 名称空间
摘要:在程序中,只使用 using namespace std; 而不使用其他的名称空间,如using namespace boost; 这样的好处有:1、可以避免不同名称空间中的名称冲突;2、可以很清楚地知道某个东西在哪个名称空间内。因为在std中的东西,不再需要使用std::,而在其他名称空间内的必须使用对应的名称空间。 阅读全文
posted @ 2013-11-06 13:37 Andy Niu 阅读(282) 评论(0) 推荐(0)
boost::token_compress_on
摘要:对于场景:string s = "123456",用"3","4"切分,默认情况下(boost::token_compress_off),切分结果为12,空,56,注意,这里的空不是空格。而是"3","4"之间的空。如果不想要这个空,指定boost::token_compress_on就行了。boost::token_compress_on的意思就是说,以"3","4",切分,当出现34的时候,就把34压缩成整体,用"34"切分。 阅读全文
posted @ 2013-11-06 12:24 Andy Niu 阅读(4965) 评论(0) 推荐(1)
指针与引用
摘要:1、引用的使用场景:必须指向某个对象(不能指向Null),并且从始至终都指向这个对象。还有一种情况:操作符的返回值要求是引用,这样就可以对它赋值。2、指针的使用场景:不适合使用引用,就使用指针。3、能使用引用,尽量使用引用。因为引用相对更高效,不需要判断指向是否为Null4、引用相对更安全,引用和指针都有不安全的情况,也就是指向的内容被销毁了。5、指针指向的内容被销毁,该指针就是野指针,野指针不是Null指针。产生野指针的情况有: a、指针变量没有初始化,指针变量创建时,取值是随机的,不是Null,因此指针变量定义时,要么初始化为Null,要么初始化为合法的内存。 b、对指针进行了dele.. 阅读全文
posted @ 2013-11-06 12:14 Andy Niu 阅读(434) 评论(0) 推荐(0)
容器的end()方法
摘要:容器的end()方法,返回一个迭代器,需要注意:这个迭代器不指向实际的元素,而是表示末端元素的下一个元素,这个迭代器起一个哨兵的作用,表示已经处理完所有的元素。因此,在查找的时候,返回的迭代器,不等于end(),说明找到了目标。等于end(),说明检查了所有元素,没有找到目标。 阅读全文
posted @ 2013-11-05 21:07 Andy Niu 阅读(1001) 评论(0) 推荐(0)
C++ map注意事项
摘要:1、在map中,由key查找value时,首先要判断map中是否包含key。2、如果不检查,直接返回map[key],可能会出现意想不到的行为。如果map包含key,没有问题,如果map不包含key,使用下标有一个危险的副作用,会在map中插入一个key的元素,value取默认值,返回value。也就是说,map[key]不可能返回null。3、map提供了两种方式,查看是否包含key,m.count(key),m.find(key)。4、m.count(key):由于map不包含重复的key,因此m.count(key)取值为0,或者1,表示是否包含。5、m.find(key):返回迭代器, 阅读全文
posted @ 2013-11-05 20:58 Andy Niu 阅读(72462) 评论(0) 推荐(3)
C++ foreach
摘要:考虑下面的需求,对vector中的每个元素加1,如何做?1 void add(int& lhs) // 注意:要修改主调方法中的数据,这里要使用引用2 {3 lhs= lhs + 1;4 }5 int intArray[] = {1,2,3,4,5};6 vector intVector(intArray,intArray+5);1、最原始的做法:1 for(vector::iterator iter=intVector.begin();iter!=intVector.end();iter++)2 {3 add(*iter);4 }2、使用类似b... 阅读全文
posted @ 2013-11-05 20:00 Andy Niu 阅读(59710) 评论(0) 推荐(1)
C++ 初始化与赋值
摘要:1、初始化与赋值的区别: 二者的区别不是看,是否有=这个赋值操作符,而是看操作的时候,对象是否已经有值。 初始化:创建对象,并给它设置初始值。 赋值:对象已经有值,擦除对象的当前值,并使用新值代替。2、初始化分为直接初始化和copy初始化。 直接初始化:直接调用与实参匹配的构造方法。 copy初始化:也叫copy构造,总是调用copy构造方法。copy构造方法就是这样的,Person(const Person& rhs),也就是根据已有的对象,copy对象的内容,形成一个副本。3、一方面:定义对象的时候,肯定调用某个构造方法进行了初始化,包括显示或者隐式。另一方面,对象的初始化必须是. 阅读全文
posted @ 2013-11-04 18:34 Andy Niu 阅读(993) 评论(0) 推荐(0)
内存泄漏
摘要:1、程序结束后,程序(实际上是指进程)占用的内存全部释放,不管是栈上的内存还是堆上的内存,包括泄漏的内存,全部释放。因为进程都不在了,OS会把进程的所有资源回收。2、因此,所谓的内存泄漏只是存在于程序运行过程中。3、内存泄漏:在程序运行过程中,对于一块确定不再使用的内存,没有人工delete,才会造成内存泄漏。4、假设一块内存,在程序的整个运行过程中都要使用,这种情况下这块内存是不能释放的,否则会引起未定义行为。必须等到程序结束后,OS来回收内存。5、假设指针指向一块申请的内存A,然后再指向一块申请的内存B,对于内存A,以后永远不会在使用,没有对内存A进行delete,造成内存泄漏。OS不会释 阅读全文
posted @ 2013-10-30 20:02 Andy Niu 阅读(242) 评论(0) 推荐(0)
区分copy构造与copy赋值
摘要:1、 Widget w1; //调用Default构造方法 Widget w2(w1); //调用copy构造方法 w1 = w2; //调用copy赋值操作符 Widget w3 = w2; //调用copy构造方法2、 对于Widget w3 = w2; 是调用copy构造方法,为什么? 因为定义一个对象的时候,肯定要调用构造方法。因此,对于Widget w3(w2) 和Widget w3 = w2表达的意思一样,都是以W2为蓝本,copy构造对象W3。3、方法调用做了两件事:a、用实参初始化形参;b、控制权交给被调方法。 被调方法的执行,以形参的定义和初始... 阅读全文
posted @ 2013-10-30 19:42 Andy Niu 阅读(263) 评论(0) 推荐(0)
shared_ptr注意事项
摘要:对shared_ptr的Copy构造和Copy赋值,会改变引用计数,但是对shared_ptr中原始资源的Copy构造和Copy赋值,不会改变引用计数。因此存在下面的危险情况:1、获取资源时,初始化指针p,然后才用shared_ptr封装资源,这意味着,又可能shared_ptr已经释放了资源,还在使用p,造成未定义行为。这种问题的解决办法就是RAII2、全局变量,取得shared_ptr中的原始资源,又可能shared_ptr已经释放了资源,还在使用全局变量,造成未定义行为。这种问题的解决办法是,全局变量不要获取shared_ptr的原始资源。对于已经存在的接口,需要传递原始资源,是没问题的 阅读全文
posted @ 2013-10-29 20:51 Andy Niu 阅读(619) 评论(0) 推荐(0)
内存分配的确定
摘要:对于下面的情况,应该在Heap上分配内存:1、对象比较大(要考虑包含的对象的大小),栈的大小有限,不宜分配很大的对象。2、创建之后,还要在其他地方经常使用,要进行频繁的传递。对象比较大,以及频繁的传递,都会导致Copy代价较大。Copy代价大,为什么不使用引用呢? 引用必须进行初始化(先有真名,再有别名),有些地方可以使用引用,比如方法的形参。有些地方不能使用引用,比如存在关联关系的对象,不能引用另一个对象,只能通过指针。 阅读全文
posted @ 2013-10-29 20:39 Andy Niu 阅读(204) 评论(0) 推荐(0)
boost 互斥体和锁
摘要:1、共享资源是一个自动锁住的房间,互斥体是钥匙,进入房间必须取钥匙,离开房间应该还钥匙。这就对应着互斥体的lock(取钥匙)和unlock(还钥匙)。2、考虑下面的场景:还钥匙的时候出现异常,会发生什么? 导致死锁,因为钥匙归还失败,所有人都没法再取到钥匙。3、如何解决这个问题? 想一下,动态分配内存存在类似的情况。如果忘记delete,会导致内存泄漏。它是如何解决的? 在栈上分配对象,要一个特点,那就是离开作用域后,对象肯定要调用析构方法。利用这个特点,可以使用对象对指针封装,在对象的析构方法中进行delete,就保证了一定会执行delete。这就是智能指针。因为智能指针,不是针对一个特.. 阅读全文
posted @ 2013-10-25 19:17 Andy Niu 阅读(4269) 评论(0) 推荐(0)
boost 线程、互斥体、条件变量
摘要:1、任何技术都是针对特定场景设计的,也就是说,为了解决某个问题而设计的。2、考虑下面一种场景:一个小旅馆,只有一个卫生间,有清洁人员,店主人,和旅客。卫生间用完之后,就会自动锁闭,必须取钥匙,才能进入卫生间。3、在上面的场景中,卫生间是共享资源,清洁人员和旅客使用卫生间的过程,就是两个线程,钥匙是互斥体。4、假定卫生间只有一个坑,一次只能一个人使用,因此就只有一个钥匙。谁要使用卫生间,必须拿到钥匙。别人拿到钥匙,自己必须等待,拿钥匙就是,程序中lock互斥体。5、通过钥匙保证了,卫生间一次只能一个人使用。这样的好处是:通过一个小钥匙,控制了一大块资源的使用。6、钥匙保证了,不同人之间不能同时使 阅读全文
posted @ 2013-10-24 19:41 Andy Niu 阅读(1623) 评论(0) 推荐(1)
C++ 迭代器类别
摘要:1、output迭代器:一次一步,只能向前,流水线上放着一批空的盒子,每次向前移动一个,往盒子里面塞一个东西。2、input迭代器:一次一步,只能向前,流水线上放着一批零件,每次向前移动一个,可以看这个零件,但是不能加工。3、forward迭代器:继承input迭代器,可以加工零件。4、bidirectional迭代器:继承forward迭代器,可以向后移。5、random access迭代器:继承bidirectional迭代器,可以一次移动多个位置。 阅读全文
posted @ 2013-10-23 19:58 Andy Niu 阅读(683) 评论(0) 推荐(0)

上一页 1 2 3 4 5 6 7 下一页