随笔 - 576  文章 - 0  评论 - 62  阅读 - 219万
12 2013 档案
【10】令operator=返回一个reference to *this
摘要:1、令operator= 返回一个reference to *this,为什么? 这只是一个协议,并无强制性。但是,为了与基本类型的行为保持一致性,强烈建议这么做。设计class 有一个宝典:一旦有疑惑,请参考int类型的行为,并遵循之。2、不光operator=,与它类似的赋值相关运算,也应该遵循该协议。 阅读全文
posted @ 2013-12-31 19:40 Andy Niu 阅读(211) 评论(0) 推荐(0) 编辑
【34】区分接口继承和实现继承
摘要:1、接口继承和实现继承表示的意义 接口继承:父类提供的接口,子类仍然提供。 实现继承:子类复用父类的代码实现。2、子类继承父类,可分为下列情况: a、继承接口,继承实现---对应non-virtual方法。 b、继承接口,继承缺省实现,允许子类修改实现---对应virtual方法。 c、只继承接口---对应pure virtual方法,父类只提供接口,强制子类提供实现。 b、关闭接口,继承实现:private继承,表示根据某物实现出,子类关闭接口。3、现在,考虑下面的场景:父类有个virtual方法XXX(),目的是让子类继承缺省实现,允许子类修改。现在有个子类,应该重写XXX,但... 阅读全文
posted @ 2013-12-31 19:20 Andy Niu 阅读(453) 评论(0) 推荐(0) 编辑
【33】避免遮掩继承而来的名称
摘要:1、首先讲讲作用域,内层作用域的名称会遮掩外层作用域相同的名称。而且遮掩规则是:只看名称,不关心名称的类型。也就是说,内层double类型的x会遮掩外层int类型的x。2、继承有两层含义:从行为和状态看,子类更加具体化;从范围看,父类是大范围,子类是小范围,可以认为子类作用域嵌套在父类作用域中。3、那么问题来了,子类作用域嵌套在父类作用域中,根据上面的遮掩规则,子类名称会遮掩父类的名称,不关心名称的类型。4、这也就意味着,子类不能过载父类的方法,因为会遮掩。如果确实要过载父类的方法,怎么办呢? 使用using Base::XXX。明确告诉编译器,我要继承父类的XXX方法(这个XXX名称对应着. 阅读全文
posted @ 2013-12-31 18:30 Andy Niu 阅读(357) 评论(0) 推荐(0) 编辑
调用异步方法
摘要:1、Bug描述 使用boost串口编程,main方法调用异步read,传入回调方法,运行程序,出现 “串口读取位置...时发生访问冲突”。而在main方法中,使用串行,while(true){read, write ,} 不会报错。2、最后问题,终于找到了。使用同步方法,main方法不会退出,而使用异步方法,main方法退出,这个时候再去执行 回调方法的时候,当然会报错,main方法都退出了。3、解决办法:使用异步方法的时候,main方法使用while(true){sleep;} 紧接思考,如果main方法不再做其他事,直接使用同步方法就好了。因为异步方法的使用场景是:去让别人做一件事(别人. 阅读全文
posted @ 2013-12-27 20:03 Andy Niu 阅读(565) 评论(0) 推荐(0) 编辑
Python 调用C++
摘要:1、C++代码提供Python需要的接口: 1 #include "stdafx.h" 2 #include 3 #include 4 using namespace std; 5 6 string greet() 7 { 8 for(int i=0;i>> import hello4 >>> hello.greet()5 'hello'6 >>> 阅读全文
posted @ 2013-12-27 19:33 Andy Niu 阅读(431) 评论(0) 推荐(0) 编辑
【37】绝不重新定义继承而来的缺省参数值
摘要:1、由于【36】绝不重新定义继承而来的non-virtual方法,现只考虑带有缺省参数值的virtual方法。2、为什么绝不重新定义继承而来的缺省参数值? 缺省参数值是静态绑定,virtual方法是动态绑定。现在考虑父类virtual方法带有缺省参数值,子类重写了virtual方法,父类指针指向子类对象,调用virtual方法,导致的结果是:用父类的缺省参数值初始化形参,调用子类重写的方法实现。这肯定不是程序员预期的结果。3、怎么解决这个问题? 使用NVI,父类通过non-virtual方法调用virtual方法,父类non-virtual方法使用缺省参数值,父类virtrual方法不使用.. 阅读全文
posted @ 2013-12-27 19:01 Andy Niu 阅读(404) 评论(0) 推荐(0) 编辑
【36】绝不重新定义继承而来的non-virtual方法
摘要:1、绝不重新定义继承而来的non-virtual方法,为什么? 首先想想,non-virtual方法是干什么的?也就是说,它的使用场景。父类的non-virtual方法,其实就是告诉子类,继承实现,子类决定是否继承接口(也就是子类决定是否继续提供接口)。如果重新定义了non-virtual方法,就不符合它的使用场景。2、如果想重新定义继承而来的方法,应该把父类方法修改为virtual方法,因为virtual方法的使用场景是:父类告诉子类,继承接口,修改实现。3、如果重新定义了继承而来的non-virtual方法,会出现什么问题呢? 因为non-virtual方法是静态绑定,也就是说,调用n.. 阅读全文
posted @ 2013-12-27 18:42 Andy Niu 阅读(342) 评论(0) 推荐(0) 编辑
【38】通过复合塑模出Has-A 或根据某物实现出
摘要:1、什么是复合? 复合是类型之间的一种关系,某种类型的对象内含其他类型的对象。2、为什么需要复合,他解决什么问题? 为了代码复用。3、复合有两层含义:Has-A和根据某物实现出。在应用域中,表示Has-A,比如:Person有一个地址,有一个所属公司。在实现域,表示根据某物实现出,比如缓冲区,互斥器等概念。4、复合可以分为:关联,聚集,组合。关联是1对1的关系,聚集和组合是多对1的关系。组合比聚集的关系更紧密,举例来说,大雁聚集成雁群,两个翅膀(和其他的部位)组合成大雁。5、关联与依赖有区别,关联表示内含一个对象,依赖表示执行一个动作的时候,依赖形参。比如:Person关联地址,Perso.. 阅读全文
posted @ 2013-12-27 18:31 Andy Niu 阅读(333) 评论(0) 推荐(0) 编辑
【转】C++ function、bind以及lamda表达式
摘要:本文是C++0x系列的第四篇,主要是内容是C++0x中新增的lambda表达式, function对象和bind机制。之所以把这三块放在一起讲,是因为这三块之间有着非常密切的关系,通过对比学习,加深对这部分内容的理解。在开始之间,首先要讲一个概念,closure(闭包),这个概念是理解lambda的基础。下面我们来看看wikipedia上对于计算机领域的closure的定义:Aclosure(alsolexical closure,function closureorfunction value)is afunctiontogether witha referencing environmen 阅读全文
posted @ 2013-12-24 19:28 Andy Niu 阅读(7441) 评论(1) 推荐(0) 编辑
【35】考虑virtual方法以外的其他选择
摘要:1、使用Non-Virtual Interface 实现方法模版 将虚方法声明为private,子类重写private的虚方法,在父类中通过public方法调用虚方法。NVI的优点是:可以在虚方法之前和之后做一些事情。2、使用方法指针实现策略模式 在类中关联一个方法指针,方法指针的形参是类对象的引用。实例化一个对象的时候,把一个方法传递给对象,这就意味着每个对象都有一个方法。这种方式提供了一些有趣的弹性:a、同一类型的不同对象可以有不同的计算方法;b、在运行期可以更改对象的计算方法。这种方式的缺点是:计算方法不能访问protected成员,要解决这个问题,只能弱化类的封装。3、使用tr1:.. 阅读全文
posted @ 2013-12-24 19:22 Andy Niu 阅读(223) 评论(0) 推荐(0) 编辑
C++多态的实现与局限性
摘要:1、什么是多态? 父类指针指向子类对象,运行时期调用方法的时候,根据方法拥有者的真实类型,确定调用哪个方法。2、如何实现多态? 要实现多态,需要加一个中间层,暴露父类的方法,内部根据指针的真实类型决议方法。 C++多态的实现方法是:每个类对应一个虚方法表vtbl,子类把父类的虚方法整体拷贝一份,对于重写的虚方法进行置换,换成重写后的方法。每个类对象内有一个vptr指向本类的虚方法表,无论父类对象还是子类对象,vptr都在相同位置。也就是说,即使编译器把子类对象当成父类对象来解释,也是没有问题的,在同样位置可以找到vptr,然后调用相应的方法。3、显而易见,C++实现多态,要求每个类都有一... 阅读全文
posted @ 2013-12-24 18:54 Andy Niu 阅读(1187) 评论(0) 推荐(0) 编辑
代码复用
摘要:1、代码复用有两个方式:继承和复合。2、继承分为public继承和private继承,public继承是继承接口,也就是父类提供的接口,子类承若仍然提供,内部有可能修改实现,子类与父类是IS-A关系。private继承是继承实现,父类提供的接口,子类不再提供,子类与父类不是IS-A的关系,不满足里氏代换,private表示的意义是,根据某物来实现。3、复合可以分为关联,聚合,组合。关联是一对一的关系,聚合和组合都是多对一的关系,但二者的紧密程度不一样。举例来说,大雁聚合成雁群,翅膀和脚组合成大雁。复合表示的意义也是,根据某物来实现。更合理的说法应该是,委托某物去做某件事。4、关联与依赖不同,关 阅读全文
posted @ 2013-12-23 19:19 Andy Niu 阅读(745) 评论(0) 推荐(0) 编辑
C++ 过载,重写,隐藏
摘要:1、过载:在一个类中(也就是一个作用域),方法名相同,形参表不同的方法。2、重写:父类方法使用virtual,子类方法和方法的方法名,形参表,返回类型相同,子类可以不使用virtual,但是建议使用virtual方法。3、子类和父类的方法名相同,除了重写的情况下,都是隐藏。4、为什么搞出隐藏? 隐藏的本质就是,子类对象无法调用,与子类方法同名的父类方法。这样做有什么意义呢? 首先考虑,Base有方法Say(),Derived有方法Say(int),子类对象调用方法的时候,少写了参数,比如derived.Say() 就会变成调用父类的方法,这和程序员的期望不一样。有了隐藏,编译器明确表示错误.. 阅读全文
posted @ 2013-12-23 19:04 Andy Niu 阅读(899) 评论(0) 推荐(0) 编辑
理解CRC校验
摘要:举个最简单的例子,A向B发送一个数字,B如何检测数字在传输过程中有没有发生错误呢? A和B之间,定下一个协议,两边都知道一个除数X,A向B发送数字的时候,同时把余数附带后面发过去。比如,两边定的除数是5,A发的数字是13,那么A实际发的数据可以认为是 13&3,B接收到这个数据,知道前面是被除数,后面是余数。检查数字传输过程是否出错的办法是 (13-3)/ 5 是否整除,如果不整除,可以认为数字传输过程中,肯定出错,比如发来的数据是 11&3。只能检查部分出错的情况,比如传输过程变成18&3,不能检查出错误。 阅读全文
posted @ 2013-12-23 18:45 Andy Niu 阅读(473) 评论(0) 推荐(0) 编辑
理解virtual方法
摘要:1、使用场景 virtual方法的使用场景:父类告诉子类,继承接口,修改实现,从而可以面向接口编程。 non-virtual方法的使用场景:父类告诉子类,继承接口和实现,从而可以代码复用。2、成员方法是一种封装技术,暴露给程序员。对于编译器而言,没有成员方法的概念,编译器会把成员方法编译为普通方法,方法的拥有者(也就是对象)转化为普通方法的形参,这个形参是const指针,名称为this,指向的类型是方法拥有者的类型。3、编译器编译的时候,只知道指针的表面类型,正是这个表面类型引导编译器去解释指向对象的大小和内容,那么问题来了? 对于non-virtual方法,子类继承接口和实现,继承的方... 阅读全文
posted @ 2013-12-23 18:25 Andy Niu 阅读(2485) 评论(0) 推荐(0) 编辑
C++ 继承的访问权限
摘要:1、它解决什么问题?为什么设计出继承的各种访问权限? 可以这样认为,C++继承会把父类的东西拉到自己这里,这些东西都是自己的,父类中的字段和方法都有访问权限,如果我想改变这些东西的访问权限,该怎么办?C++继承的访问权限就是为了解决这个问题。2、它是如何解决的? a、public继承,对于继承的东西,子类访问权限和父类一样; b、protected继承,对于继承的东西,父类public在子类降级为protected,其它不变; c、private继承,对于继承的东西,父类public和protected在子类降级为private,其它不变。3、子类继承父类的所有东西,只不过有些内容不能... 阅读全文
posted @ 2013-12-20 19:54 Andy Niu 阅读(986) 评论(0) 推荐(0) 编辑
理解奇偶校验
摘要:1、它解决什么问题? 数据传输过程中可能出错,接收方想知道传输过程是否出错。2、它是如何解决的? 以奇校验为例说明,发送方和接收方约定,发的数据(一组bit)必定是奇数个1。接收方对接受的数据进行检查,如果数据中1的个数不是奇数,认为数据传输过程中,出现了错误,要求发送方再次发送。那么问题来了,发送方如何保证发送的数据一定有奇数个1呢?答案是增加一个调节位。如果发送的内容已经是奇数个1,调节位填0,如果发送的内容是偶数个1,调节位填1。从而保证了发送的数据(发送的数据内容+调节位)一定是奇数个1。3、优点和缺点 优点是简单,方便。 缺点是,只能检查错误,不能纠正错误,而且只能检查一部分... 阅读全文
posted @ 2013-12-20 18:52 Andy Niu 阅读(780) 评论(0) 推荐(0) 编辑
程序员语录
摘要:程序员编程语录 1. 一个好的程序员是那种过单行线马路都要往两边看的人。(Doug Linder) 2. 程序有问题时不要担心。如果所有东西都没问题,你就失业了。(软件工程的 Mosher 定律) 3. 程序员的麻烦在于,你无法弄清他在捣腾什么,当你最终弄明白时,也许已经晚了。(超级计算机之父 Seymour Cray) 4. 我想大部分人都知道通常一个程序员会具有的美德。当然了,有三种:懒惰,暴躁,傲慢。(Perl 语言发明者 Larry Wall) 5. 编程时要保持这种心态:就好象将来要维护你这些代码的人是一位残暴的精神病患者,而且他知道你住在哪。(MartinGoldin... 阅读全文
posted @ 2013-12-19 20:23 Andy Niu 阅读(515) 评论(0) 推荐(0) 编辑
理解虚方法
摘要:1、什么是虚方法? 考虑Animal* pa = new Dog(); pa表面类型是Animal,实际类型是Dog。可以理解为,pa说,我指向Animal,说法是对的。但是不具体,实际上,pa指向Dog。pa->Say()是虚方法,在编译期,编译器只知道pa 的表面类型,不知道该调用Animal 的Say方法还是Dog 的Say方法,所以才叫做“虚方法”。只有在运行期,才根据pa 的真实类型,确定调用哪个方法。这就是虚方法。2、为什么需要虚方法?它解决了什么问题? 简单说,就是为了面向接口编程,库的提供者暴露接口,隐藏实现。库的使用者不需要知道内部的实现细节。3、它是如何解决的? 虚方 阅读全文
posted @ 2013-12-18 20:23 Andy Niu 阅读(523) 评论(0) 推荐(0) 编辑
不同类型的指针
摘要:1、思考,不同类型的指针,到底有什么区别? 指向Animal的指针和指向Dog的指针,到底有什么区别?首先,指针的表示方法相同,指针的内容相同,都是一个int,表示地址。区别只是指向对象的类型不同(好像是废话)。这有什么意义呢? 这其实是告诉了编译器如何解释这个地址中的内存内容以及大小。也就是说,对于指向Animal 的指针,编译器把指向内容当作一个Animal,对于指向Dog 指针,编译器把指向的内容当作Dog。2、那么,问题来了,Animal* pa = new Dog(),是怎么做到运行期多态的呢? pa的表面类型是Animal,真实类型是Dog,编译器在编译时只知道pa的表面类型,.. 阅读全文
posted @ 2013-12-18 18:45 Andy Niu 阅读(1628) 评论(0) 推荐(1) 编辑
C++ 对象模型
摘要:1、C++对象内存包含两部分:字段和虚方法表指针vptr,vptr指向vtbl,vtbl包含类型信息和一组虚方法,虚方法按照类的定义顺序进行排列。2、成员方法并不占用对象内存,无论是static方法,还是non-static方法。3、那么,思考一下,对象是如何绑定到成员方法的呢? 对于程序员,方法分为成员方法和普通方法。对于编译器,没有成员方法,因为成员方法,会转化为普通方法。比如person.SetName(),对于编译器来说,会转化为SetName(person),student.SetName()转化为SetName(student)。3、那么问题来了,这种方式,显然无法满足,运行时多. 阅读全文
posted @ 2013-12-13 20:15 Andy Niu 阅读(209) 评论(0) 推荐(0) 编辑
为什么需要模版成员方法
摘要:1、解决的问题: 考虑下面的需求,有个集合模版vector,实例化一个类vector,一个类vector,创建对象 double_Vector和int_Vector,我想把int_Vector赋值给double_Vector,这个需求是合理的。思考一下,能成功吗?2、我们知道,同一个模版实例化出来的模板类,之间没有任何关系,是不同的类型,根本不可能赋值的,因为编译器生成的copy构造和copy赋值,形参都是同一类型。double_Vector的copy构造和copy赋值的形参都是vector对象,那现在怎么办呢?3、解决办法: 建立模版成员方法,copy构造模版成员方法和copy赋值模版成.. 阅读全文
posted @ 2013-12-13 19:58 Andy Niu 阅读(302) 评论(0) 推荐(0) 编辑
理解 traits
摘要:1、为什么使用traits? 考虑下面的需求,实现一个方法Advance(iter,n),接收一个迭代器iter和移动距离n,将iter向前移动n个距离。 分析,因为存在不同类型的迭代器,做同一件事情,大家的能力不一样,做法当然不一样。有的迭代器可以一下子移到目标,有的迭代器只能一步一步移动,进行n次。因此,在方法内,必须要判断迭代器的类型,然后进行相应的操作。这种方法当然不好,运行期判断类型,需要核对继承层次中的每个类,效率差。有没有更好的办法呢?2、解决办法: a、每个迭代器暴露一个接口,暴露自己类型的别名(使用typedef MyType Category),每个迭代器都使用相同的... 阅读全文
posted @ 2013-12-13 19:42 Andy Niu 阅读(363) 评论(0) 推荐(0) 编辑
C++ 异常处理
摘要:1、异常处理分为两个部分:抛出异常和捕获异常。2、抛出异常,类似于方法返回值,离开了作用域,局部对象销毁,因此需要有一个临时对象保存结果。C++特别强调,抛出一个异常,必定要一个临时对象接收,存在copy构造,这是不可避免的,因为抛出的异常已经离开了作用域,失去了控制权。3、捕获异常,类似于调用方法,将临时对象传递给catch中的局部对象,为了避免再次copy构造,catch语句应该使用引用。特别注意,内置类型的临时对象是不可修改的,也就是说,内置类型的临时对象不能赋值给non-const引用,但是异常对象是可以的,catch语句可以是non-const引用。4、捕获异常与调用方法的区别: . 阅读全文
posted @ 2013-12-13 19:04 Andy Niu 阅读(355) 评论(0) 推荐(0) 编辑
传const引用代替传值
摘要:1、为什么使用传const引用? a、被调方法中,形参不再进行copy构造,以及析构,提高效率。 b、传值,会出现对象切割的问题。2、有没有例外? 在编译器底层,引用是使用指针实现的。这就意味着,如果对象是内置类型,迭代器,函数对象,传值效率更高。因为传引用也就是传指针,而内置类型,迭代器,函数对象copy构造效率也很高,不会比copy构造指针效率差。 阅读全文
posted @ 2013-12-13 18:37 Andy Niu 阅读(1043) 评论(0) 推荐(0) 编辑
争吵
摘要:1、软件开发工程中,常常出现争吵,为什么争吵? 存在两个解决方案,都有合理性。合理性越接近,争吵越激烈,比如合理性是5:5。如何合理性是9:1,估计不会争吵。2、争吵中,忌讳为私利。比如一个方案的合理性是4,但是这个方案对自己有利,自己可以少干活或者实现起来比较容易。3、争吵中,忌讳死不认错。为了维护自己的面子,拼命强调自己方案的合理性,指责别人方案的不合理性。同时不肯承认别人方案的合理性以及自己方案的不合理性。4、争吵中,忌讳太强势。有些人,自己的方案优于别人,争吵获胜后,还要嘲笑别人,从而显示自己的能力,这种人很惹人烦。做人要自信,坚强,认真,宽容,还要内敛,不要得理不饶人,处处显得比别. 阅读全文
posted @ 2013-12-13 18:18 Andy Niu 阅读(256) 评论(0) 推荐(0) 编辑
理解仿函数
摘要:1、考虑下面的需求,vector中放置Person,Person有age和name字段。在vector中查找第一个Person c,这个很简单,方法如下: vector::iterator iter = find(personVector.begin(),personVector.end(),c); 注意:find算法使用操作符==,比较对象是否相等,需要提供==重载。2、考虑下面的需求,在vector中查找第一个age>15的Person。使用find_if和仿函数。如下: iter = find_if(personVector.begin(),personVector.end(),G 阅读全文
posted @ 2013-12-10 20:52 Andy Niu 阅读(662) 评论(0) 推荐(0) 编辑
成员方法与const之间的关系
摘要:const可以放在成员方法的三个地方,前、中、后。首先考虑在中间:1、const修饰形参,表示形参是否为const2、如果const修饰引用(指针指向的对象),可以进行过载,如果不是修饰引用(指针指向的对象),不能进行过载。为什么? 首先考虑引用,引用是一个对象的别名,在调用的时候,编译器根据原对象的常量性,可以找到一个最匹配的方法。const修饰指针指向的对象,和引用是同样的道理。如果const不是修饰引用或者指针指向的对象,就不能过载。因为,这种情况下,是整体拷贝,拷贝后的对象和原对象没有了任何关系。指针本身的常量性,不能过载,也是同样道理。3、考虑下面的情况,有方法 void SetA. 阅读全文
posted @ 2013-12-07 22:13 Andy Niu 阅读(851) 评论(0) 推荐(0) 编辑
学习C++
摘要:1、在可用可不用C++的地方,由于C++的难,会慢慢淘汰C++,因此C++会慢慢趋向于精英化,有些地方,目前还是必须使用C++。2、学习热门的东西,并不一定好。热门的东西必定大众化,虽然需求很大,但是学习的人也很多。C++难,使用的项目少,需求少。坚持下来的人少,相对而言,还是一样。3、基础往往是最重要的,基础学好,想上学很快。反过来,就很慢。 阅读全文
posted @ 2013-12-07 21:25 Andy Niu 阅读(223) 评论(0) 推荐(0) 编辑
软件开发的难
摘要:软件开发的难,往往不是做不到,而是复杂。比如:让一个建筑工人找一个原子弹,这是属于做不到的“难”。让他造一座房子,属于复杂,耗时耗精力的“难”,并不是做不到。这里还涉及到一个问题,复杂的东西能够做到,还要做的质量好。质量好的房子和质量差的房子,往往从表面看不出来。比如,好的房子电线出现问题,很快定位修好,如果很差的房子,电线出现问题,根本摸不着头脑,必须把墙全部砸开,看看里面的线路布置。 阅读全文
posted @ 2013-12-07 21:18 Andy Niu 阅读(283) 评论(0) 推荐(0) 编辑
理解软件
摘要:软件的本质是什么,该如何理解?1、所有的软件,无非是增删改查和数据的可视化。Google也就是做了一个查,只不过查的对象是整个互联网内容,互联网上的用户进行增删改操作。阿里巴巴也就是对商品的增删改查。2、软件的本质是,根据已知的实现,对这些实现封装,对外暴露接口。操作系统对硬件封装,对外暴露接口。高级编程语言对操作系统进行封装,对外暴露接口。引用软件对高级语言封装,对外暴露接口,很多是人机接口。3、可以把软件的运行看成做一件事,比如做菜。做菜需要菜谱,菜谱列出了需要哪些原料和操作步骤,人按照操作步骤,加工数据。菜谱就是程序,原料就是数据,操作步骤就是程序的控制流程,人就是CPU,人做菜就是CP 阅读全文
posted @ 2013-12-07 21:08 Andy Niu 阅读(247) 评论(0) 推荐(0) 编辑
理解模板
摘要:为什么要设计出模板,他解决什么问题?1、首先考虑类模板: 考虑下面的需求:工厂生产玩具,根据模具生产出玩具。现实当中的模具生产出来的玩具都是一样的,假设我们的模具比较高级,能够设置玩具的属性,生产出不一样的玩具。比如玩具狗,可以生出不一样的玩具狗,但是这些狗有一组相同的属性,比如大小,颜色,形状等,这些属性可能不同。如果没有设置玩具狗的属性,会有一个默认值。这里的狗模具就是类,生产出的玩具狗,就是对象,或者说实例。 接着思考,工厂扩大,需要生产玩具猫,玩具猴,怎么办?首先要做的就是,先造出猫模具,猴模具,有没有更好的办法呢? 比如说,先搞出一个生产模具的模具,这样的话,只要告诉我,生产某... 阅读全文
posted @ 2013-12-07 20:57 Andy Niu 阅读(226) 评论(0) 推荐(0) 编辑
引用计数
摘要:什么是引用计数?一个在堆上创建的对象,记录有多少个指针指向它。为什么要设计引用计数,他解决什么问题?1、new出一个临时对象,使用完了,需要delete。但是拥有权会转移(auto_ptr)或者扩散,因此很难确定delete时机。忘记delete导致资源泄漏,过早delete,导致还在使用的指针出现错误,重复delete导致未定义行为。2、许多对象拥有相同的值,存储多次是个很愚蠢的事,可以共享。如何实现:1、以String为例说明,String s1 = "Hello", String s2 = s1; 可以让s1,s2共享"Hello"。2、引用计数放 阅读全文
posted @ 2013-12-02 20:45 Andy Niu 阅读(1360) 评论(0) 推荐(0) 编辑
C++为什么不支持某些东西
摘要:1、学习C++的过程,经常发现C++不支持一些东西,思考下,为什么?2、C++不支持一些东西,有两个原因: a、可以做到,但是会导致一些不合理的结果,这些结果往往与程序员的期望不一致。 b、属于“臣妾做不到啊”3、对于第一种情况,比如: a、传引用,存在隐式类型转换,会建立一个临时对象。对引用的修改,不能体现在原对象身上,与程序员期望不一致,C++不支持。 b、p++++,编译器不支持。4、对于第二种情况,比如: C++不支持模版的分离式编译。5、C++能做什么,不能做什么,往往是由C++编译器决定的。C++做不到,往往是因为编译器做不到。比如: a、比如,不能这样创建对象Pers... 阅读全文
posted @ 2013-12-02 19:44 Andy Niu 阅读(271) 评论(0) 推荐(0) 编辑
C++ 不支持模版的分离式编译
摘要:1、C++不支持模版的分离式编译,为什么? C++是分别,单独编译,对于每个cpp文件,预编译为编译单元,这个编译单元是自包含文件,编译的时候,不需要其他的文件,编译好了,生成obj文件,然后连接成exe文件。在编译的时候,使用一个东西,如果这个东西就在当前位置,当然好了。如果不再当前位置,也没关系,只要说,我有这个东西就行,这个东西在其他地方。在连接的时候,会找到这个东西在什么地方。 考虑普通方法,通过上面的分析,是没有问题的。考虑模版方法: Fun.h声明一个方法模版,Fun.cpp包含Fun.h,并定义了方法模版,main.cpp包含Fun.h,然后使用方法。单独编译Fun.cpp... 阅读全文
posted @ 2013-12-02 19:34 Andy Niu 阅读(1355) 评论(0) 推荐(0) 编辑
方法名重整
摘要:1、为什么要进行方法名重整? C++支持过载,允许方法名相同,形参表不同。对于同名的方法,编译器根据形参表的不同,对方法名重整为另一个方法名,也就是建立一种映射。这就是为什么要进行方法名重整。同时编译器,进行了扩展,也就是说,没有过载的方法也进行了方法名重整。2、方法名重整带来的问题 C中没有过载的概念,也就是不允许出现同名的方法。因此,也就没有方法名重整。考虑下面的情况:在C++使用C语言库中的方法,int add(int a);C中提供了add方法的实现,C++中包含头文件,声明方法,然后使用。C代码生成的目标文件中,方法名没有重整,还是add,而C++代码方法名进行了重整,假设重整为.. 阅读全文
posted @ 2013-12-02 19:01 Andy Niu 阅读(259) 评论(0) 推荐(0) 编辑
前缀式与后缀式
摘要:1、考虑下面的场景:有一个Person类,内部有个age字段,对外提供前缀式和后缀式,把年龄加1。2、前缀式与后缀式都没有右操作数,也就是说没有形参,需要区分前缀式和后缀式,对于后缀式中增加一个形参。因为这个形参在方法内并不使用,可以省略形参名。3、前缀式和后缀式是操作符重载,本质上是方法,和GetName()一样。4、前缀式:1 Person& Person::operator ++()2 {3 this->age = this->age+1;4 return *this;5 }5、后缀式:1 const Person Person::operator ++(int)2 阅读全文
posted @ 2013-12-02 18:29 Andy Niu 阅读(3473) 评论(0) 推荐(0) 编辑

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示