我的C++使用心得

静态库链接

C++静态库的链接问题。C++静态库(.a)存在重复定义符号(函数)的风险。说明如下:
  (1)、在a文件中定义函数f,编译生成a.o
  (2)、在b文件中定义同样原型的函数f,实现与a中不同,编译生成b.o
  (3)、将a.o,b.o打包到同一个静态库文件c.a
  (4)、使用f,并链接c.a,将导致链接到第一个找到的符号。
总结:神坑,不知道怎么填。

异常

请先看下面一段C++代码片段

    mutex.lock();
    f();
    mutex.unlock();

对于上面一段代码,f()需要同步。于是执行前进行加锁操作,执行后解锁。这个一眼看去逻辑很正常。
那么问题在哪儿呢?
异常!
对于C++的异常,熟悉的朋友可能知道对于可能抛出异常的接口调用时,需要用

    try
    {
    }catch()
    {
    }

进行捕获异常。那么问题是对于一些接口我们有时候并不知道它是否会抛出异常。

但是一旦抛出异常,那么当前函数将终止执行后续代码片段。
并且将异常根据函数调用栈层层返回,直到有一层进行捕获或者终止程序运行。
所有上面的代码,如果f()执行过程中抛出异常,那么mutex.unlock()将不会被执行。

改进方法:利用栈上对象自动回收的机制,让系统进行自动加锁解锁操作。

    class A
    {
    public:
        A() { mutex.lock(); }
        ~A() { mutex.unlock(); }
    };

    {
        A guard;
        f();
    }

当代码执行到大括号里面时,构造gurad对象进行加锁操作。当执行完f()离开大括号,析构guard对象,解锁。
上面的代码即使f()里面抛出异常,一样会将加锁解锁完整闭环执行完。

内联函数

书上面能找到的这里就不提了。
这里要说的是,当在头文件中声明成员函数,却在多个实现文件中实现(均实现为inline函数)的情况。
这里存在2个问题:
(1)、编译器是否会报告重复定义或者找不到实现?
    针对 gcc 版本 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC),测试结果如下。
    首先,绝对不会报告重复定义错误。
    其次,有可能报告找不到实现。
(2)、如果不会重复定义,那么TMD那到底会使用哪个或者哪些实现呢?
    根据情况而定。
看到这里,是不是有种感觉这是在逗你玩的感觉。并非。我的测试demo表明,你实现inline的位置,并非为绑定具体实现到声明的位置。
他(编译器)会在按连接目标文件的次序,当连接到第一个使用该函数的目标文件,从该文件中查找并绑定该函数。之后使用该函数,无论  是否出现其他实现,均不会影响该绑定。
按照此原则,若第一次出现使用该函数时,对应目标文件中无实现,则会报告找不到
实现(基础知识嘛,对吧)。

常量

(1)头文件中可以定义非静态常量,不会出现重复定义错误。编译器会进行折叠优化。