目录
参数规则
1、不要偷懒
2、命名要清晰直接
3、熟悉使用const
返回值规则
1、不要偷懒
2、提高效率
3、返回值的安全
内部实现规则
1、合法性检查
2、通用细节
该章节重点讲了函数设计应该注意的地方。
参数规则
1、不要偷懒
参数的书写要完整,不能贪图省事只写参数的类型而省略参数的名字,没有参数的话用void填充
void Add(int ,int );
//不良好的风格
void Add(int a,int b);
//良好的风格
void GetVal();
//不良好的风格
void GetVal(void);
//良好的风格
2、命名要清晰直接
书上给出了一个例子
void StringCopy(char* str1, char* str2);
从函数名可以看出这是一个字符串拷贝函数,但是从形参的命名,看不出到底是把str1内的类容拷贝到str2里面还是反过来,所以形参也不要随便命名。
如果把参数改成这样:
void StringCopy(char* strDestination, char* strSource);
这样就很有辨识度,一眼就能看出将后一个字符串拷贝给前一个字符串
这些是主观上的改变,但是为了确保使用者不小心把传参顺序弄反了,还是需要在代码层面上进行改进,避免这种情况的发生。
void StringCopy(char* strDestination, const char* strSource);
利用const修饰变量,该变量的内容无法被修改,这样也确保了源的安全性。
3、熟悉使用const
- 如果参数是指针,且仅作输入用,则应在类型前加const,以防止该指针在函数体内被意外修改。
- 如果输入参数以值传递的方式传递对象,则宜改用“const &”方式来传递,这样可以省去临时对象的构造和析构过程,从而提高效率。(这里涉及到引用的知识)
同样的,与参数传递一样,返回值类型也千万不要偷懒说省就省。在C语言中,凡是不加类型说明的函数一律按照整型处理。
在C++中会有很严格的类型安全检查,不写返回值的类型会报错。
无论是C还是在C++中都得明确返回值类型,没有返回值也必须声明成void类型。
函数有些时候不需要返回值,但是为了增加灵活性附加返回值。
例如库函数中的strcpy
char *strcpy(char *strDest,const char *strSrc);
这个返回值的目的是为了链式访问,是的代码更加灵活简洁。
int length = strlen( strcpy(str, “Hello World”) );
//链式表达
2、提高效率
C++中的引用传递会提高不少的效率,减少拷贝次数。
例如:
string_t& operator=(const string_t& s)//深拷贝
{
if (this != &s)//避免无效拷贝
{
delete[] _str;
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
}
return *this;
}
如果直接传值的话,会额外拷贝一次(内存会开辟一个临时对象),降低效率。
但是引用也不能随便传,如果引用传递是一个临时变量,函数结束后会自动销毁,这是一个非常危险的操作,留下隐患。
3、返回值的安全
return语句不要返回在栈上定义的指针或者引用,因为一旦出了作用域(函数结束)会被自动销毁
内部实现规则 1、合法性检查
有些情况参数传递是不合法的,需要在入口处进行合法性检查。这里需要正确的使用断言assert来防止此类错误。
assert是仅在Debug 版本起作用的宏,它用于检查“不应该”发生的情况。可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。
不仅要检查输入参数的有效性,还要检查通过其它途径进入函数体内的变量的有效性,例如全局变量、文件句柄等。
2、通用细节
- 函数的功能要单一,不要设计多用途的函数。
- 函数体的规模要小,尽量控制在50 行代码之内。
- 尽量避免函数带有“记忆”功能。例如static的局部变量
推荐阅读
- 数据结构|数据结构 - 堆
- linux|Linux基本指令
- 数据结构|二叉树需要掌握的基本知识
- 读书|读高质量C++/C编程指南第4章
- 读书|读高质量C++/C编程指南1-3章
- 数据结构|八大经典排序算法
- 前端|Vue 学习笔记(一)
- 程序员|Android面试题精选——再聊Android-Handler机制-2,android实战教程
- 帅到起飞,在thymeleaf中使用自定义工具类