随笔 - 576  文章 - 0  评论 - 62  阅读 - 219万

随笔分类 -  C++

上一页 1 2 3 4 5 6 7 下一页
char指针
摘要:1、在C语言中,没有字符串类型,因此使用char指针表示字符串。2、那么问题来了,使用char* 表示字符串,到哪里是结尾呢?因此需要一个特殊的字符作为哨兵,类似迭代器中的end(),这个哨兵就是'\0',注意不是字符0.3、对于文本字符串,编译器会自动添加\0。4、对于字符数组的赋值,如果不使用文本字符串,需要用户在尾部添加字符\0。对于其他类型的数组,没有\0的概念。5、对于char指针,C语言提供了一系列方法,如strlen,strcmp。这些方法有个特点,都是假定最后一个字符为\0。因此对于char指针,我们要保证最后一个字符是\0。6、考虑sizeof,对于指针,取值 阅读全文
posted @ 2014-02-20 21:39 Andy Niu 阅读(3267) 评论(0) 推荐(1) 编辑
main方法执行之前,做什么事
摘要:1、我们知道程序的入口是main方法,那么在执行main方法之前,需要做些什么准备工作呢?2、main方法执行之前,必须要把non-local static对象构造完成。static对象有:全局对象,命名空间中的对象,类的static对象(从封装的角度看,类也是一个命名空间),方法内的static对象,其中方法中的static对象是local static对象,其他的是non-local static对象,这些对象分配在全局区,程序结束才释放内存。3、local static对象直到方法被调用的时候,才进行初始化,而且只初始化一次。non-local static必须在main方法执行之前,进 阅读全文
posted @ 2014-02-20 20:05 Andy Niu 阅读(4567) 评论(0) 推荐(0) 编辑
C++复制控制
摘要:1、复制控制包括:copy构造,copy赋值,析构方法。2、没有声明任何构造方法,编译器自动生成一个default构造方法。对于copy构造,copy赋值和析构方法,没有声明,编译器会自动合成一个。3、合成的copy构造,做的事情是:逐个字段初始化,将新对象初始化为原对象的一个副本。所谓的逐个成员初始化,只是指实例字段,不包括static字段,因为static字段是共享的。如果字段是值类型,直接赋值。如果字段是类类型,递归调用copy构造方法。有个情况很例外,一般情况下,不能复制数组,但是对于类中的数组,合成copy构造将复制数组中的每一个元素。4、合成的copy赋值,做的事情:除了stati 阅读全文
posted @ 2014-02-20 19:28 Andy Niu 阅读(748) 评论(0) 推荐(0) 编辑
C++访问权限
摘要:1、C++类本身没有访问权限的概念,就是class Base。2、类成员的访问权限有:public、protected、private3、类的继承方式有:public、protected、private 阅读全文
posted @ 2014-02-20 18:56 Andy Niu 阅读(280) 评论(0) 推荐(0) 编辑
C++ struct与class
摘要:1、相对于C中struct,C++做了很大的扩充。基本上和class 差不多。只有一些细节上的差别。2、对于成员的默认访问权限,class是private,struct是public。需要注意的是,程序中应该明确指出访问权限,不要依赖默认的访问权限。对于其它默认的情况也是一样,尽量明确指出来,这是一个良好的编程习惯,增加代码的可读性。3、对于默认的继承方式,class是private,struct是public。需要注意的是,class可继承class,也可继承struct。struct可继承struct,也可继承class。默认的继承方式取决于子类是struct还是class。和上面一样,这 阅读全文
posted @ 2014-02-20 18:53 Andy Niu 阅读(1972) 评论(0) 推荐(0) 编辑
char数组与char指针
摘要:1、以字符串形式出现的,编译器会在结尾自动添加\0,思考,为什么? 存在的C语言方法,如strlen(s),计算字符串的长度,其中s指针。strlen要计算字符串长度,必须知道哪里是结尾,因此使用\0表示结尾。只有字符数组才有\0的概念,其它类型(int)的数组没有这个概念。因为其他类型的数组或者... 阅读全文
posted @ 2014-02-17 20:48 Andy Niu 阅读(58956) 评论(4) 推荐(1) 编辑
stack对象与heap对象
摘要:从高地址到低地址,分别是stack,heap,static object,stack地址往下增长,heap地址往上增长。只要记住:stack栈顶地址反而小,就知道往下增长了。禁止产生堆对象1、产生堆对象使用new operator,可认为new operator有三个过程: a、使用operator new操作符搜索可用的内存,分配一块内存; b、在这块内存上,调用构造方法构造一个对象; c、返回地址。2、要禁止产生堆对象,可以声明类的operator new为private,禁止分配内存就好了。为了保持一致性,将operator delete也重载为private。3、注意:new o... 阅读全文
posted @ 2014-02-13 20:01 Andy Niu 阅读(940) 评论(0) 推荐(1) 编辑
对象切割与临时对象
摘要:1、判断是copy构造还是copy赋值,不是看是否有赋值操作符=,而是看对象当前是否已经有值了。如果没有值,就是copy构造。如果已经有值了,就是copy赋值。2、对象赋值的时候,源端与目标端类型不吻合,肯定要进行一次适配(而且只能是一次),中间产生一个临时对象。3、比如:Person p; p = 6; copy赋值的时候,要求rhs是个const Person&,显然6不是。因此,这里适配一下,用6构造一个临时对象,然后rhs指向这个临时对象。 那么接着思考,子类对象赋值给父类对象,会造成对象切割。那么这个过程是否产生临时对象呢?Person p; Student s; p=s; 阅读全文
posted @ 2014-02-12 18:34 Andy Niu 阅读(728) 评论(0) 推荐(0) 编辑
【转】placement new
摘要:原文:http://www.cnblogs.com/wanghetao/archive/2011/11/21/2257403.html1. placementnew的含义placementnew是重载operatornew的一个标准、全局的版本,它不能够被自定义的版本代替(不像普通版本的operatornew和operatordelete能够被替换)。void*operatornew(size_t,void*p)throw(){returnp;}placementnew的执行忽略了size_t参数,只返还第二个参数。其结果是允许用户把一个对象放到一个特定的地方,达到调用构造函数的效果。和其他普 阅读全文
posted @ 2014-01-24 20:02 Andy Niu 阅读(250) 评论(0) 推荐(0) 编辑
理解shared_ptr<T> ---2
摘要:1、引用计数字段不能放在资源管理类中。我们的解决办法是,把引用计数和资源绑在一起,进行二次封装。但是这样存在一个大问题,不同类型的资源管理类不能兼容。也就是说,shared_ptr不能赋值给shared_ptr。2、你可能会想,使用模版成员方法去解决,但是这里有个问题。因为进行了两次封装,u_ptr的类型还是不一样,也不能赋值。你可能会想,我在u_ptr中也建立模版成员方法,这也是错的。思考下,我们要保证,资源管理类指向同一个u_ptr,对u_ptr进行拷贝,那么资源管理类就不是指向同一个u_ptr了,这显然是错的。3、有没有其它的办法呢? 问题的关键是,进行了两次封装。不进行两次封装就好了. 阅读全文
posted @ 2014-01-17 21:22 Andy Niu 阅读(835) 评论(0) 推荐(0) 编辑
理解shared_ptr<T>
摘要:1、shared_ptr解决什么问题? auto_ptr有个局限,拥有权转移。这往往不符合我们的需求,有时候我们期望,多个资源管理对象可以共享一个资源,当引用计数为0的时候,执行delete。shared_ptr就是为了解决这个问题。2、shared_ptr怎么解决这个问题?和auto_ptr类似,除此之外,还有几点需要注意:3、增加一个字段为引用计数,当引用计数为0的时候,执行delete。引用计数字段不能放在资源管理类中,为什么? 假设放到资源管理类中,每个资源管理对象都有一个refCount字段,共享一个资源的资源管理对象的refCount取值一样,但是怎么保持一致呢?因为这些对象之.. 阅读全文
posted @ 2014-01-17 19:05 Andy Niu 阅读(1746) 评论(0) 推荐(0) 编辑
理解 auto_ptr<T>
摘要:1、auto_ptr解决什么问题? 在堆上获取的资源,客户可能会忘记delete,或者由于异常没有执行到delete,导致资源泄漏。在栈上分配的对象,有个特点,不论出现什么情况,超出作用域后,都将调用析构方法。根据这个特点,可以使用栈上的对象管理指针,析构的时候执行delete,确保一定释放资源。2、auto_ptr就是解决这个问题的,auto_ptr就是个资源管理类,它的特点是拥有权转移。3、考虑,如果让我来设计auto_ptr,我该怎么做? auto_ptr是个资源管理类,对指针封装。有几点需要注意: a、可以对不同类型的指针进行封装,因此需要一个模板类。 b、copy构造,cop... 阅读全文
posted @ 2014-01-17 18:40 Andy Niu 阅读(829) 评论(0) 推荐(0) 编辑
C++ 外部调用private方法
摘要:1、思考,对于C++,能不能在外部调用私有方法?2、在Java中,子类继承不能缩小父类成员的访问权限。因为在Java中,继承只是表示Is-A关系,因此,父类提供的接口,子类必须承诺仍然提供,不能缩小访问权限,但是可以放大权限。3、在C++中,继承不光表示Is-A关系,还可以表示根据某物实现出。因此,在C++中,子类可以放大或者缩小父类成员的访问权限。考虑,如果父类提供public virtual方法,子类重写为private virtual方法,我们知道,重写只不过是,子类整体拷贝父类的虚方法表,对于重写的方法偷梁换柱,替换为重写后的方法。在这种情况下,父类指针指向子类对象,父类指针通过调用p 阅读全文
posted @ 2014-01-16 20:34 Andy Niu 阅读(4822) 评论(0) 推荐(1) 编辑
C++ 构造过程和析构过程
摘要:1、C++构造和析构的过程,类似于穿衣脱衣的过程。穿衣是:先穿内衣,再穿外套。脱衣是:先脱外套,再脱内衣。C++构造过程:首先调用父类构造方法,再调用子类构造方法。C++析构过程:首先调用子类析构方法,再调用父类析构方法。2、子类不能继承父类的构造方法和析构方法,除此之外,其他的成员都能继承,包括父类的private成员,只不过子类不能访问private成员。3、思考一下,为什么子类不能继承父类的构造方法? 想一想,构造方法是干什么的?构造方法是初始化对象的成分,创建对象。从语义上讲,父类构造方法初始化父类成分,构造父类对象。子类构造方法在父类对象的基础上,初始化子类专有成分,构造子类对象。. 阅读全文
posted @ 2014-01-16 19:12 Andy Niu 阅读(4054) 评论(0) 推荐(1) 编辑
成员方法的this指针
摘要:1、我们知道成员方法中,有个隐式的this常量指针。考虑,Derived继承的成员方法中this指针的表面类型是什么?子类重写的虚方法中this指针的表面类型是什么?2、Derived继承的方法,就是Base的那个方法,this指针的表面类型是Base*,也就是把this指针当成Base来解释。3、子类重写的方法中,this指针的表面类型是Derived*,也就是把this指针当成Derived来解释。注意:子类重写父类的方法,需要重新声明。 阅读全文
posted @ 2014-01-10 18:57 Andy Niu 阅读(347) 评论(0) 推荐(0) 编辑
C++ 初始化与赋值
摘要:1、变量三要素:类型,名称,值。定义变量的时候,提供初始值,定义时指定了初始值的对象称为已初始化的。C++支持两种初始化形式:直接初始化,赋值初始化。如下: int ival(1024); // 直接初始化 int ival = 1024; // 赋值初始化2、初始化与赋值是两个概念。初始化:创建对象时赋给初始值。赋值:擦除对象的当前值,并用新值代替。因此,判断是初始化还是赋值的关键是,看看对象当前是否已经存在值了。3、初始化调用copy构造方法,赋值调用copy复制操作符。 阅读全文
posted @ 2014-01-08 18:28 Andy Niu 阅读(507) 评论(0) 推荐(0) 编辑
C++ 变量初始化规则
摘要:1、定义变量的时候,如果没有初始化,它的值是什么呢? 它的值取决于变量的类型和变量定义的位置。2、考虑基本类型的变量,定义时没有初始化。如果定义在方法外部,初始化为0,如果定义在方法内部,不被初始化。使用未初始化的变量,导致未定义行为。未初始化的变量事实上,也有一个值,这个值是随机的。因此强烈建议,基本类型的变量都要初始化,也就是方法内部的变量。3、考虑类类型的变量,定义时没有初始化。不管定义在哪里,都会调用默认构造方法,这种情况下,必须提供默认构造方法,如果没有,编译出错。也就是说,对于类类型的变量,不存在没有初始化的情况,因为没有显式初始化,会调用默认构造方法进行隐式初始化。 阅读全文
posted @ 2014-01-07 20:32 Andy Niu 阅读(1009) 评论(0) 推荐(0) 编辑
C++ 构造和析构
摘要:1、继承关系可认为,子类在父类的基础上进行。从这个角度讲,可把它认为穿衣脱衣的过程。穿衣是:先穿内衣,再穿外套。脱衣是:先脱外套,在脱内衣。构造是:先调用父类构造方法,再调用子类构造方法。析构是:先调用子类析构方法,再调用父类析构方法。2、构造可分为两个步骤:初始化列表和方法内赋值。前者的使用场景是:初始化,即copy构造。后者的使用场景是:赋值,即copy赋值。 a、对于类类型,如果没有在初始化列表中显式初始化,会进行隐式初始化,调用默认构造方法。因此,没有默认构造方法的类成员,必须显式初始化。 b、对于基本类型,如果没有在初始化列表中显式初始化,不会进行隐式初始化。初始值依赖于对象的作.. 阅读全文
posted @ 2014-01-07 19:49 Andy Niu 阅读(442) 评论(0) 推荐(0) 编辑
C++ int与string的转化
摘要:int本身也要用一串字符表示,前后没有双引号,告诉编译器把它当作一个数解释。缺省情况下,是当成10进制(dec)来解释,如果想用8进制,16进制,怎么办?加上前缀,告诉编译器按照不同进制去解释。8进制(oct)---前缀加0,16进制(hex)---前缀加0x或者0X。string前后加上双引号,告诉编译器把它当成一串字符来解释。注意:对于字符,需要区分字符和字符表示的数值。比如:chara = 8;charb = '8',a表示第8个字符,b表示字符8,是第56个字符。int转化为string1、使用itoa(int to string) 1 //char *itoa( in 阅读全文
posted @ 2014-01-03 19:29 Andy Niu 阅读(335963) 评论(5) 推荐(8) 编辑
理解C++ 宏
摘要:1、什么是宏,它解决什么问题? 宏的本质是文本替换,考虑下面的需求,程序中多次使用圆周率Pi,在每个地方都使用3.1415,显然很愚蠢。有没有好的办法呢?使用宏,如下: #definePi 3.1415 这样,编译器在程序中遇到Pi,就使用3.1415来进行文本替换。2、特殊字符 考虑下面的需求,程序中多处使用文本字符串。我们知道文本字符串前后都要加上双引号,我很讨厌输入双引号。有没有好的办法呢?根据常识,使用下面的宏: #define Str(x) "x" String s = Str(Hello); 期望预编译为:String s = "Hello" 阅读全文
posted @ 2014-01-02 21:53 Andy Niu 阅读(2126) 评论(0) 推荐(0) 编辑

上一页 1 2 3 4 5 6 7 下一页
< 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

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