c++编程技巧

1、enum(枚举)没有枚举名

如果声明枚举类型时没有指定枚举名,其作用就和#define类似,比如以下代码:

enum {
    STATION_IDLE = 0,
    STATION_CONNECTING,
    STATION_WRONG_PASSWORD,
    STATION_NO_AP_FOUND,
    STATION_CONNECT_FAIL,
    STATION_GOT_IP
};

这里声明了一个枚举类型确没有指定其枚举名,那么它就相当于用#define定义了六个名称和其对应的值,从0开始赋值每次加1,相当于:

#define     STATION_IDLE = 0;
#define     STATION_CONNECTING = 1;
#define     STATION_WRONG_PASSWORD = 2;
#define     STATION_NO_AP_FOUND = 3;
#define     STATION_CONNECT_FAIL = 4;
#define     STATION_GOT_IP = 5;

只不过eunm类型表示的是一个确定的值,而这里#define了六个值,可见如果要表示同一个事件的不同反馈status,使用这种没有枚举名的枚举效果更好。

2、#pragma GCC diagnostic 编译器警告

头文件中有如下代码

#elif defined __GNUC__

  #if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) &&  (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
    #pragma GCC diagnostic push
  #endif
  // g++ warns about local variables shadowing member functions, which is too strict
  #pragma GCC diagnostic ignored "-Wshadow"
  #if __GNUC__ == 4 && __GNUC_MINOR__ < 8
    // Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions:
    #pragma GCC diagnostic ignored "-Wtype-limits"
  #endif
  #if __GNUC__>=6
    #pragma GCC diagnostic ignored "-Wignored-attributes"
  #endif

#endif

gcc编译器中

各个层次的gcc警告
从上到下覆盖

变量(代码)级:指定某个变量警告
int a __attribute__ ((unused));
指定该变量为"未使用的".即使这个变量没有被使用,编译时也会忽略则个警告输出.

文件级:在源代码文件中诊断(忽略/警告)
语法:
#pragma GCC diagnostic [error|warning|ignored] "-W<警告选项>"r"

诊断-忽略:(关闭警告)
#pragma  GCC diagnostic ignored  "-Wunused"
#pragma  GCC diagnostic ignored  "-Wunused-parameter"

诊断-警告:(开启警告)
#pragma  GCC diagnostic warning  "-Wunused"
#pragma  GCC diagnostic warning  "-Wunused-parameter"

诊断-错误:(开启警告-升级为错误)
#pragma  GCC diagnostic error  "-Wunused"
#pragma  GCC diagnostic error  "-Wunused-paramete

用法:
在文件开头处关闭警告,在文件结尾出再开启警告,这样可以忽略该文件中的指定警告.

项目级:命令行/编译参数指定

警告:
gcc main.c -Wall 忽略:
gcc mian.c -Wall -Wno-unused-parameter //开去all警告,但是忽略 -unused-parameter警告

选项格式: -W[no-]<警告选项>
如 : -Wno-unused-parameter # no- 表示诊断时忽略这个警告

扫描二维码关注公众号,回复: 6743652 查看本文章

3、函数指针typedef void (*T) (void *)的理解

void (*Func) (void *)定义了一个指向函数的指针,函数的返回值为 void 类型,后面的(void *)是函数的参数列表, void * 表示参数列表为void,加typedef表示函数指针的别名为Func,不加typedef也可以,但影响代码的阅读。

接下来我们就可以直接使用Func 来定义这种指针变量,

比如:Func fn1; //等价于void fn1 (void *);

使用:void func(void *); //声明函数
Func fn1; //定义变量
fn1=func; //赋值
(*fn1)(); //执行 

typedef void (*intFunc)(int);//要定义的类型是void (*)(int),即参数一个int,什么也不返回的函数指针,定义的别名是intFunc。

在ros中NodeHandle类中subscribe()函数的几个重载版本都用了函数指针做形参,如下

template<class M, class T>
Subscriber subscribe(const std::string& topic, uint32_t queue_size, void(T::*fp)(M), T* obj, const TransportHints& transport_hints = TransportHints())
{
  SubscribeOptions ops;
  ops.template initByFullCallbackType<M>(topic, queue_size, boost::bind(fp, obj, _1));
  ops.transport_hints = transport_hints;
  return subscribe(ops);
}

...................

项目级:命令行/编译参数指定

警告:
gcc main.c -Wall 忽略:
gcc mian.c -Wall -Wno-unused-parameter //开去all警告,但是忽略 -unused-parameter警告

选项格式: -W[no-]<警告选项>
如 : -Wno-unused-parameter # no- 表示诊断时忽略这个警告

3、函数指针typedef void (*T) (void *)的理解

void (*Func) (void *)定义了一个指向函数的指针,函数的返回值为 void 类型,后面的(void *)是函数的参数列表, void * 表示参数列表为void,加typedef表示函数指针的别名为Func,不加typedef也可以,但影响代码的阅读。

接下来我们就可以直接使用Func 来定义这种指针变量,

比如:Func fn1; //等价于void fn1 (void *);

使用:void func(void *); //声明函数
Func fn1; //定义变量
fn1=func; //赋值
(*fn1)(); //执行 

typedef void (*intFunc)(int);//要定义的类型是void (*)(int),即参数一个int,什么也不返回的函数指针,定义的别名是intFunc。

在ros中NodeHandle类中subscribe()函数的几个重载版本都用了函数指针做形参,如下

template<class M, class T>
Subscriber subscribe(const std::string& topic, uint32_t queue_size, void(T::*fp)(M), T* obj, const TransportHints& transport_hints = TransportHints())
{
  SubscribeOptions ops;
  ops.template initByFullCallbackType<M>(topic, queue_size, boost::bind(fp, obj, _1));
  ops.transport_hints = transport_hints;
  return subscribe(ops);
}

...................

猜你喜欢

转载自www.cnblogs.com/kerngeeksund/p/11066485.html