浅谈C与C++的设计与编程风格(二)
上次总结了C++(面向对象)设计的核心思想,并且例举了使用类模型来替代if和switch的一种较为典型的情况。下面想来谈谈C++在编码方面的特点。
在很多经典的C++教程中都有一个建议:应尽量使用户代码(库的使用者)看起来短小而简单。按照常识,简单的代码通常要比大段的代码好理解,而用户代码通常实现的是最上层的功能或者界面,它的不确定性更大,经验告诉我们,最容易出错的代码正是那些被频繁修改的代码!因此简单的用户代码是有好处的,在开发一个库时我们应尽量遵守这个建议。
C++有两个机制可以帮助我们实现这一点,一个是运算符重载,另一个就是模板。
C++的运算符重载机制非常强大,这里就举一个简单的例子。C语言中有一种对数组的特殊初始化方式,比如:int a[4] = {1,4,2,3}; 这样的语法非常清晰且容易让人理解,然而很可惜的是,这样的语法不能用于对数组的赋值,对数组的赋值必须使用一个循环操作,当这个数组中的内容不是按顺序排列时,对数组的赋值很可能会演变成一个非常复杂的过程。
但是在C++中,我们却可以利用重载运算符来实现一种相似的赋值语法,方法就是我们设计一个迭代器,并重载该迭代器的 , 运算符,然后再设计一个可以使用这个迭代器的数组类,并重载这个数组的=运算符,它们的代码大致会是这样:
// 一个重载了,运算符的迭代器类
class CCopyIterator
{
int * m_piItem;
public:
CCopyIterator(int in_aiItems[])
{
m_piItem = in_aiItems;
};
CCopyIterator & operator ,(int in_iVal)
{
*(m_piItem++) = in_iVal;
return *this;
}
};
//可以使用CCopyIterator赋值的数组
class CSmartArray
{
int m_aiItems[100]; // 这里使用一个定长的数组是为了回避回收内存空间的问题,毕竟这不是我们要讨论的主要问题
public:
CCopyIterator operator =(int in_iFirstVal)
{
CopyIterator rtn(m_aiItems);
return (rtn, in_iFirstVal);
}
相关文档:
Boss说,要看OpenGL,看了快一个月,总算出了个像样的东西,用C写了个3D迷宫,
虽然只有350行
代码,不过边学边写,足足写了一周时间,还是小有成就感的,活活活!
&n ......
/*编写程序,输入2个数以及加减乘除中的某运算符号,并调用自己编写的函数计算相应的结果*/
#include<stdio.h>
#include<conio.h>
float cal(int a,char sym,int b);
main()
{
int a=0,b=0;
char sym='\0';
float c=0.0;
scanf("%d%c%d",&a,&sym,&b);
c=c ......
C宏实例
摘自Linux内核2.6.21.5源码(部分),展示了链表的另一种实现思路
未采用ANSI C标准,采用GNU C标准,遵从GPL版权许可。
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_ ......
在C/C++中我们有时为了节省内存占用空间,需要使用到位域,如下所示代码:
struct SDummy
{
int A : 2;
int B : 8;
int C : 12;
int D : 10;
};
在计算机内存昂贵的情况下,位域不乏为一种有效的节省内存占用空间又让代码书写比较通俗易懂的方法。但是在现今内存相 ......
有次一个同事问我
swc ^= swc;
是什么意思,我也不知道,查了下,意思应该是将swc变量清0,疑惑的是为什么就不能写成 swc = 0; 呢?不明白
顺便记录下其他的操作,碰到新的再追加:
swc = ~swc; //变量取反 ......