随笔分类 -  c & cpp

摘要:I/O操作符号(<<和>>)返回数值 最近博问里有几个问题都牵涉到这一点了,简单做笔记说明一下。 首先cin是一个对象,不会"返回"值,>>和<<才是方法,具有返回值。>>和<<操作符的运算顺序是由左向右边,所以下面的两种语句描述其实是一致的: cin>>a>>b>>c; (((cin>>a)>>b)>>c);操作cin>>a的意义: 调用istream 的operator>>方... 阅读全文
posted @ 2012-03-27 21:24 zsounder 阅读(1728) 评论(2) 推荐(2) 编辑
摘要:这是德问技术社区的一个问题,测试了一下,使用typeid等方法都无法正确区分二者,不讨论二者是不是有必要进行区分;下面给出一个方案吧,其实就是利用了Traits,模板的匹配规则。 1: template<typename T> class _ischararray_; 2: 3: template<typename T, int N> 4: class _ischararray_<T[N]> { public: static bool _ischararray(){return true;}}; 5: 6: template<typename T... 阅读全文
posted @ 2012-03-09 11:00 zsounder 阅读(1036) 评论(0) 推荐(4) 编辑
摘要:一篇介绍C++ Traits的文章:An introduction to C++ Traits,分享一下,后面会针对Traits做一点总结。It is not uncommon to see different pieces of code that have basically the same structure, but contain variation in the details. Ideally we would be able to reuse the structure, and factor out the variations. In 'C' this m 阅读全文
posted @ 2012-03-09 10:45 zsounder 阅读(397) 评论(0) 推荐(0) 编辑
摘要:几年前整理的,最近有人问起,先放在这里,改天整理一下,前端时间忙,该开始整理一下笔记里的东西了,以后定时更新博客咯。源码下载单继承模式下,虚继承 1: #ifndef OM_SINGLE_VIRTUAL_INHERITANCE_H_ 2: #define OM_SINGLE_VIRTUAL_INHERITANCE_H_ 3: // 单继承模式下,虚拟继承 4: // 若子类没有新定义virtual函数 此时子类的布局是 : 5: // 低地址 -> 高地址 6: // vbptr,子类的元素, 虚基类的元素. 7: // 在虚基类派生出来的... 阅读全文
posted @ 2012-03-01 00:53 zsounder 阅读(699) 评论(2) 推荐(2) 编辑
摘要:摘要: STL里有仿函数的概念,而在应用仿函数的时候,仿函数与仿函数之间的适配引出了约束器的概念。这一节主要叙述一下一元函数对象基类unary_function、二元函数对象基类binary_function,以及两个约束器binder1st与binder2nd,同时给出一个场景,分析实现原理。 1:template <class Arg, class Result> struct unary_function;2:template <class Arg1, class Arg2, class Result> struct binary_function; 3: tem 阅读全文
posted @ 2011-06-15 09:19 zsounder 阅读(414) 评论(0) 推荐(1) 编辑
摘要:今天面试的时候,被问到了一个问题:release版本下new了一个对象A, 将A传入debug版本库,发生错误?可能的原因是什么呢?debug模式下: 1: // debug模式下的new 2: #define new DEBUG_NEW 3: 4: // DEBUG_NEW如下 5: #define DEBUG_NEW new(THIS_FILE, __LINE__) 6: 7: // 对于如上的new,编译器会寻找如下定义的operator new 8: void* AFX_CDECL operator new(size_t nSize... 阅读全文
posted @ 2011-03-28 22:29 zsounder 阅读(2350) 评论(0) 推荐(0) 编辑
摘要:我没参加过笔试呢,不过经常有人拿着笔试中的问题来问我,特别是++、--运算符的问题, 其实这些问题应该从基本原理上理解一下,但是在笔试中这种问题还是有个简单的方法计算才好。总结以下的几条:1) 在计算中,对于一个作用域内的前缀操作数(++i),替换为i的最终数值,对于后缀操作符替换为原数值。2) 在printf,cout等依靠堆栈工作的方法中,对于一个作用域内的前缀操作符(++i),替换为i的最终数值,对于后缀操作符,按照入栈顺序分析。 1: int a ; 2: //-------------------------------------------------... 阅读全文
posted @ 2011-03-27 18:25 zsounder 阅读(889) 评论(0) 推荐(0) 编辑
摘要:重载运算符是对正常函数的语法美化.没给语言增加任何基本的东西,但改善了可理解性并降低维护费用.当用户需要时,就应该使用运算符重载,但应该仅仅以用户熟悉的语义方式来使用它。1. 重载规则不能重载的运算符: . 和 .* 和 ?: 和 :: 和 sizeof 和 typeid重载运算符有两种基本选择: 类的成员函数或者友元函数, 建议规则如下:运算符建议使用所有一元运算符成员函数= () [] ->必须是成员函数+= -= /= *= ^= &= != %= >>= <<= , 似乎带等号的都在这里了.成员函数所有其它二元运算符, 例如: –,+,*,/友元函 阅读全文
posted @ 2011-03-27 17:35 zsounder 阅读(3072) 评论(0) 推荐(1) 编辑
摘要:对于字符数组与字符指针:1. 以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写"abc",那么编译器帮你存储的是"abc\0".2. 字符串直接量作为字符指针的初始值 "hello"是一个字符串直接量,编译器将其作为const char*处理,与之相关联的内存空间位于内存的只读部分,即允许编译器重用指向等价字符串直接量的引用以优化内存使用,即使程序 中使用了字符串直接量500次,编译器在内存中也只是创建了一个实例。例如: char *ptr = “hello”; 等价于 const char *ptr = “hello”;字 阅读全文
posted @ 2011-03-26 14:22 zsounder 阅读(5394) 评论(3) 推荐(4) 编辑
摘要:1: #ifndef __INCvxWorksh 2: #define __INCvxWorksh 3: #ifdef __cplusplus 4: extern "C" { 5: #endif 6: /*...*/ 7: #ifdef __cplusplus 8: } 9: #endif 10: #endif /* __INCvxWorksh */显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用是防止该头文件被重复引用。3-9行的代码作用又是什么呢... 阅读全文
posted @ 2011-03-26 11:20 zsounder 阅读(434) 评论(0) 推荐(0) 编辑
摘要:C++中用const限定符来定义常量,但const出现的可以出现在常量定义中,也可以出现在方法定义中,并且出现的位置也有所不同,所表示的意思也不同。 在任何可能的情况下都要使用 const。在声明的变量或参数前加上关键字 const 用于指明变量值不可被篡改 (如 const int foo ). 为类中的函数加上 const 限定符表明该函数不会修改类成员变量的状态 (... 阅读全文
posted @ 2011-03-24 20:31 zsounder 阅读(957) 评论(0) 推荐(1) 编辑
摘要:1:定义: 它们看起来象函数,运作起来象函数,比宏(macro)要好得多,使用时还不需要承担函数调用的开销。当内联一个函数时,编译器可以对函数体执行特定环境下的优化工作。这样的优化对"正常"的函数调用是不可能的。2:规则: inline关键字必须和函数体定义放在一起才可以实现内联,仅仅将inline放在函数声明之前不起任何作用。inline是一个用于实现的关键字而不是一个用于声明的关键字。对于类方法,定义在类体内部的方法自动成为内联方法。3:实现思想: 内联函数的基本思想在于将每个函数调用以它的代码体来替换,很可能会增加整个目标代码的体积过分地使用内联所产生的程序会因为有太 阅读全文
posted @ 2011-03-24 20:06 zsounder 阅读(2544) 评论(0) 推荐(3) 编辑
摘要:1:内存对齐定义: 现在使用的计算机中内存空间都是按照字节划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际上计算机系统对于基本数据类型在内存中的存放位置都有限制,要求这些数据存储首地址是某个数K的倍数,这样各种基本数据类型在内存冲就是按照一定的规则排列的,而不是一个紧挨着一个排放,这就是内存对齐。对齐模数: 内存对齐中指定的对齐数值K成为对齐模数(Alignment Modulus)。当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格),而称T比S弱(宽松)。2:内存对齐的好处: 内存对齐作为一种强制的要求,第... 阅读全文
posted @ 2011-03-24 14:54 zsounder 阅读(3466) 评论(2) 推荐(3) 编辑
摘要:printf的声明 int _cdecl printf(const char* format, …);调用约定:_cdecl_cdecl调用约定的特点: 1). 参数从右向左依次入栈 2). 调用者负责清理堆栈 3). 参数的数量类型不会导致编译阶段的错误对x86, 栈的生长方向向下(高地址向低地址),_cdecl调用约定函数参数从右向左入栈,因此从第一个固定参数(format)的堆栈地址向前(向上,向高地址)移动就可得到其他变参的地址。1: va_list、va_start、va_arg、va_end对可变参数的支持 va_list、va_start、va_arg、va_end相关宏... 阅读全文
posted @ 2011-03-24 14:00 zsounder 阅读(1079) 评论(0) 推荐(0) 编辑
摘要:字符编码的问题让我困惑了好久的一段时间,其实简单的想,字符编码没有什么东西的,可是想真弄明白还是花去了我一点时间,前端时间写了一个简单的log程序,主要的工作就是支持系统运行时输出日志信息,同时允许定制不同级别的日志输出,刚开始的时候只是写入到文件中,可用过之后发现,只是写入到文件中,在进行系统调试的时候不是很方便,还要打开文件,浏览,再返回源代码,如果能够有一个界面展示岂不是更好,列表显示日志,可以选择显示的日志级别,实现日志输出位置的定位,类似下图中展示的一样:感觉还是能方便一点的,而显示窗口的实现可以通过exe或者dll的方式,这就需要进行两个独立进程之间的通信,为了支持多个日志显示窗. 阅读全文
posted @ 2010-05-08 20:48 zsounder 阅读(3954) 评论(1) 推荐(4) 编辑