C++技巧之宏Macro应用 - 蘭陵N散記

作者:JerryXia | 发表于 , 阅读 (0)
宏不要用来定义常量,因为宏变量是没有类型安全,也没有名字空间约束,会造成名字的污染。
宏的展开是一行,所以宏中的注释不能使用//,只能使用/* */。宏的代码也不能gdb跟踪,宏中代码逻辑要尽量简单。
宏的参数一般情况下使用时要用()括起来,如:#define MAX(a, b) a /2 > b ? a /2  : bMAX(3,4)使用没有问题,但MAX(3+4, 4)却有问题,因为宏的参数仅为符号替换。应用定义为#define MAX(a, b)  (a) / 2 >  (b) ?  (a) /2 : (b)
宏的连接符分为#与###表示一个符号直接转换为字符串,如#define CAT(x) "First "#x " Third"const char * pszStr = CAT(Second); str的内容就是”First Second Third”,也就是说#会把其后的符号直接加上双引号。##符号会连接两个符号,从而产生新的符号(词法层次),例如:#define NAME( x ) name_##xchar* NAME( szlanny ); 宏被展开后将成为:ch...阅读全文

C++技巧之operator操作符 - 蘭陵N散記

作者:JerryXia | 发表于 , 阅读 (0)
这篇博文是以前很久写的,贴在我的早期一个blog中,今天google一下,发现还真有不少人转载,可惜并不注明出处。那时觉得operator比较好玩。C++有时它的确是个耐玩的东东。operator它有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换)。
operator overloadingC++可以通过operator 重载操作符,格式如下:类型T operator 操作符 (),如比重载+,如下所示
template<typename T> class A{public:const T operator + (const T& rhs){return this->m_ + rhs;}private:T m_;};又比如STL中的函数对象,重载(),这是C++中较推荐的写法,功能与函数指针类似,如下所示
template<typename T> struct A{T operator()(const T& lhs, const T& rhs){ return lhs-rhs;}};operator c...阅读全文

C++技巧之断言Assert - 蘭陵N散記

作者:JerryXia | 发表于 , 阅读 (0)
assert的作用是先计算表达式expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用abort 来终止程序运行。
大家要注意是,其中的表达式为假时,会终止程序运行,包括我在内经常会写错代码,断言一个指针是否为空,往往写成了assert(!p);其实应该写成assert(p);。
assert是运行期的判断,并且会强制终止程序,一般要求只能用于debug版本中,是为了尽可能快的发现问题。尤其在我所从事的电信软件产品中,assert是要从release版本中去掉。所以一般开发会重新定义assert宏。
静态断言:在新的C++标准中C++0x中,加了对静态断言的支持,引入了新的关键字static_assert来表示静态断言。
使用静态断言,我们可以在程序的编译时期检测一些条件是否成立。但这个关键字太新了,没有几个编译器是支持的(好像VC2008支持,我用VC很少,主要是在linux下C++编程)。
于是可以使用C++现有的模板特性来实现静态断言的功能。boost中也已有BOOST_STATIC_ASSERT宏的实现,有兴趣的同学可以d...阅读全文

[c++]自己实现的queue - 蘭陵N散記

作者:JerryXia | 发表于 , 阅读 (0)
测试代码:void print_queue(int& a){printf("%d/t", a);}void test_queue(){LQueue<int> queue;//Queue<int, 4> queue;queue.push(1);queue.push(2);queue.push(3);queue.pop();queue.pop();queue.pop();queue.push(1);queue.push(2);queue.push(3);printf("/n1 : size: %d /n", queue.size() );queue.traverse(print_queue);queue.pop();printf("/n2 : size: %d /n", queue.size() );queue.traverse(print_queue);queue.push(4);printf("/n3 : size: %d /n", queue.size() );queue.traverse(print_queue);queue.clear();printf("/n4 : size: ...阅读全文

用C++模板来展示new与delete操作符原理 - 蘭陵N散記

作者:JerryXia | 发表于 , 阅读 (0)
第一部分是与malloc功能相同,是从堆上面申请内存块第二部是调用类的构造方法来初始化刚申请的内存。delete是new的逆过程,先调用类的析构方法来反初始化,再把刚申请的内存还给堆。
new []与delete []是针对数组操作符,要注意是通过new []分配的对象,不能用delete来释放对象,否则会有内存泄漏。当然通过new分配的对象,不能用delete[]来释放对象。后面我会通过代码来说明为什么。
下面是C++ 中的new与delete函数原型,申请内存失败会抛出异常bad_alloc
void* operator new(std::size_t) throw (std::bad_alloc);void* operator new[](std::size_t) throw (std::bad_alloc);void operator delete(void*) throw();void operator delete[](void*) throw();使用举例:
int* p1 = new int();delete p2;int* p2 = new int[5];de...阅读全文