zoukankan      html  css  js  c++  java
  • write solid code Chapter 2 练习题4 的解答与扩展

    原题:

    4、When programmers add new elements to an enumeration, they sometimes forget to add new cases to the appropriate switch statements. How could you use assertions to help detect this problem?

    附录中的答案:

    .
    .
    .
    default:
        ASSERT(FALSE); /*We should never get here*/
       break;

    把这个问题扩展下:

    看到上题的时候,想到了在u-boot中加入启动命令函数的时候曾经犯过错(还有一点,boot中的启动命令函数有点分散了,应该集中下),Z先生推荐我看下《write solid code》,无意中看了android中的源码,就有了如下的记录(非常好,以前没用过):

     1 //keywords.h
     2 #ifndef KEYWORD                                                                                                     
     3 
     4 int do_chroot(int nargs, char** args);
     5 int do_chdir(int nargs, char** args);
     6 
     7 #define __MAKE_KEYWORD_ENUM__
     8 /*
     9  *定义KEYWORD宏,此处用了宏的“粘贴”预处理,此时只用到了第一个参数
    10  */
    11 #define KEYWORD(symbol, flags, nargs, func) K_##symbol,
    12 
    13 enum {
    14     K_NUKNOWN,
    15 #endif
    16     KEYWORD(capability, OPTION, 0, NULL)
    17     KEYWORD(chdir, COMMAND, 1, do_chdir)
    18     KEYWORD(chroot, COMMAND, 1, do_chroot)
    19 
    20 #ifdef __MAKE_KEYWORD_ENUM__
    21     KEYWORD_COUNT,
    22 };
    23 
    24 #undef __MAKE_KEYWORD_ENUM__
    25 #undef KEYWORD
    26 #endif
     1 //parser.c
     2 /*                                                                                                                  
     3  *第一次包含keywords.h,根据keywords.h的代码,首先得到一个枚举定义.
     4  */
     5 #include "keywords.h"
     6 
     7 /*
     8  *重新定义KEYWORD宏,此处运用了宏的“#”预处理运算符
     9  */
    10 #define KEYWORD(symbol, flags, nargs, func) 
    11     [ K_##symbol ] = { #symbol, func, nargs + 1, flags, },
    12 
    13 /*
    14  *定义一个结构体keyword_info数组,它用来描述关键字的一些属性
    15  */
    16 struct
    17 {
    18     const char *name;                    //关键字的名称
    19     int (*func)(int nargs, char** args); //对应关键字的处理函数
    20     unsigned char nargs;                 //参数个数,每个关键字的参数个数是固定的
    21     unsigned char flags;                 //关键字的属性
    22 }keyword_info[ KEYWORD_COUNT ] = {
    23     [ K_UNKNOWN ] = { "unknown", 0, 0, 0,}, 
    24 /*
    25  *第二次包含keywords.h,由于已经重新定义了KEYWORD宏,
    26  *所以以前作为枚举值的关键字现在变成keyword_info数组
    27  *的索引了.
    28  */
    29 #include "keywords.h"
    30 };
    31 
    32 #undef KEYWORD

    在parser.c中两次包含了keywords.h文件,首次包含时列出了枚举项,可以作为后文中数组的索引;第二次包含时,由于宏已被定义,因此正好可以实现数组中的各个项。

    仿照此种实现,完全可以实现习题4的解答(一个枚举项对应一个相应的处理函数即可,而且可以通过索引来完成,比switch-case快);此外可以实现代码的集中管理,否则太分散了(不然就用grep,有点麻烦)。

  • 相关阅读:
    声明以及字符表述类--字母大小写的敏感性
    条款52:写了placement new 也要写placement delete(write placement delete if you write placement new)
    verdi知识点
    关于$test$plusargs和$value$plusargs的小结
    条款40:明智而审慎地使用多重继承(use multiple inheritance judiciously)
    条款39:明智而审慎地使用private继承(use private inheritance judiciously)
    条款38:通过复合塑模has-a或“根据某物实现出”
    条款37:绝不重新定义继承而来的缺省参数值(Never redefine a function's inherited default parameter value)
    自学nodejs系列
    五个典型的JavaScript面试题
  • 原文地址:https://www.cnblogs.com/openix/p/3182694.html
Copyright © 2011-2022 走看看