摘要: 来自C语言中的静态元素 无论什么时候设计一个包含静态变量的函数时,都应该记住多线程问题。 静态对象的析构函数 静态对象的析构函数(包括静态存储的所有对象,不仅仅是局部静态对象)在程序从main()中退出时,或者标准的C库函数exit()被调用时才被调用。 同普通对象的销毁一样,静态对象的销毁也是按与初始化时相反的顺序进行的。当然只有那些已经被创建的对象才会被销毁。 全局对象总是在main()执行之前被创建,在退出main()时销毁。 控制连接 所有的全局对象都是隐含为静态存储的,所以如果定义(在文件作用域): int a = 0; 则a被存储在程序的静态数据区,在进入... 阅读全文
posted @ 2013-11-17 23:16 sheshiji 阅读(141) 评论(0) 推荐(0)
摘要: 在C中,保持效率的一个方法是使用宏。宏可以不要普通的函数调用代价就可使之看起来像函数调用。宏的实现是用预处理器而不是编译器。预处理器直接用宏代码代替宏调用,所以就没有了参数压栈、生成汇编语言的CALL、返回参数、执行汇编语言的RETURN等的开销。所有的工作由预处理器来完成,因此不用花费什么就具有了程序调用的便利和可读性。 在C++中,使用预处理器宏存在两个问题。第一个问题在C中也存在:宏看起来像一个函数调用,但并不总是这样。这样就隐藏了难以发现的错误。第二个问题是C++特有的:预处理器不允许访问类的成员数据。这意味着与处理器宏不能用作类的成员函数。 为了既保持预处理器宏的效率又增加安... 阅读全文
posted @ 2013-11-17 23:09 sheshiji 阅读(185) 评论(0) 推荐(0)
摘要: 值替代 当用C语言进行程序设计时,预处理器可以不受限制地建立宏并用它来替代值。因为预处理器只做些文本替代,它既没有类型检查概念,也没有类型检查功能,所以预处理器的值替代会产生一些微小的问题,这些问题在C++中可以通过使用const值而避免。 比如: #define BUFFERSIZE 100 BUFFERSIZE是一个名字,它只是在预处理期间存在,因此它不占用存储空间且能放在一个头文件里,目的是为使用它的所有编译单元提供一个值。使用值替代而不是使用所谓的“不可思议的数”,这对于支持代码维护是非常重要的。 头文件里的const 要使用const而非#define,同样必须把... 阅读全文
posted @ 2013-11-17 18:33 sheshiji 阅读(183) 评论(0) 推荐(0)
摘要: 转载自:http://xiangwangfeng.com/2011/05/02/const%E7%9A%84%E5%86%85%E9%83%A8%E9%93%BE%E6%8E%A5%E5%B1%9E%E6%80%A7/ 最早注意到这个问题也是很偶然:某天发现工程里面有个头文件定义了一堆的字符常量: const std::string sKeyCode = "code"; const std::string sKeyResult = "result"; ... 阅读全文
posted @ 2013-11-17 15:33 sheshiji 阅读(808) 评论(0) 推荐(1)
摘要: 名字修饰 假设重载了两个函数名: print(float); print(char); 无论这两个函数是某个类的成员函数,还是全局函数都无关紧要。如果编译器只使用函数名的域,编译器并不能产生惟一的内部标识符,这两种情况下都得用_print结尾。重载函数的思想是让我们用同名的函数,但这些函数的参数列表应该不一样。所以,为了让重载函数正确工作,编译器要用不同的参数类型来修饰不同的函数名,以供它和连接器使用。上面的两个在全局范围定义的函数,可能会产生类似于_print_float和_print_char的内部名。但不同的编译器可能会产生不同的内部名。 C++中禁止仅仅靠返回值来... 阅读全文
posted @ 2013-11-17 12:09 sheshiji 阅读(175) 评论(0) 推荐(0)
摘要: 用构造函数确保初始化 在一个对象被定义时: X a; 这时就好像a是一个int一样:为这个对象分配内存。但是当程序执行到a的序列点执行的点时,构造函数自动被调用,因为编译器已悄悄地在a的定义点处插入了一个X::X()的调用。就像其他成员函数被调用一样。传递到构造函数的第一个(秘密)参数是this指针,也就是调用这一函数的对象的地址,不过,对构造函数来说,this指针指向一个没有被初始化的内存块,构造函数的作用就是正确的初始化该内存块。 默认构造函数 记住,一旦有了构造函数,编译器就会确保不管在什么情况下它总会被调用。 默认的构造函数非常重要,所以当一个结构或类中没有构造函数... 阅读全文
posted @ 2013-11-17 12:05 sheshiji 阅读(131) 评论(0) 推荐(0)
摘要: 对象布局 访问说明符是结构的一部分,它们并不影响从这个结构创建的对象。程序开始运行之前,所有的访问说明信息都消失了。访问说明信息通常是在编译期间消失的。在程序运行期间,对象变成了一个存储区域,别无他物。 所有的访问保护检查都是由编译器来完成的,在运行期间不再检查。 阅读全文
posted @ 2013-11-17 12:00 sheshiji 阅读(125) 评论(0) 推荐(0)
摘要: 转载自:http://blog.csdn.net/sparkliang/article/details/3670930 为了防止内存泄漏,每一个动态内存分配必须有一个等同相反的内存释放操作,delete和new相对应,也有作为操作符的delete和作为函数的delete。 第一,操作符delete,对应操作符new,释放内存,并自动调用类的析构函数,调用格式: delete pointer; 第二,函数delete,对应函数new,操作符delete会调用函数delete释放内存,函数原型是: void operator delete(void *buffer);... 阅读全文
posted @ 2013-11-17 01:00 sheshiji 阅读(599) 评论(0) 推荐(0)
摘要: 转载自:http://blog.csdn.net/sparkliang/article/details/3650324 C++中的new其实是一个很糊弄人的术语,它有两种不同的含义,new运算符(new operator)和new函数(operator new),值得记录一下。 一 new运算符 最常用的是作为运算符的new,比如: string *str = new string("test new"); 作为运算符,new和sizeof一样,是C++内置的,你不能对它做任何的改变,除了使用它。 new会在堆上分配一块内存,并会自动调用类的构造函数。 二 new函数 .. 阅读全文
posted @ 2013-11-17 00:49 sheshiji 阅读(142) 评论(0) 推荐(0)
摘要: 语言的翻译过程 静态类型检查 类型检查是检查函数参数是否正确使用,以防止许多程序设计错误。由于类型检查是在编译阶段而不是程序运行阶段进行的,所以称之为静态类型检查。 分段编译工具 程序可由多个文件构成,一个文件中的函数很可能要访问另一些文件中的函数和数据。编译一个文件时,C或C++编译器必须知道在一些文件中的函数和数据,特别是它的名字和基本用法。编译器就是要确保函数和数据被正确地使用。“告知编译器”外部函数和数据的名称及它们的模样,这一过程就是声明。一旦声明了一个函数或变量,编译器知道怎样检查对它们的引用,以确保引用正确。 声明和定义 事实上,所有的C/C++程序都要求声明。 ... 阅读全文
posted @ 2013-11-17 00:00 sheshiji 阅读(142) 评论(0) 推荐(0)