More Effective C++学习笔记(6)-杂项

主题概要
C++More Effective C++ 杂项
编辑时间
新建20170123
序号参考资料
1More effective C++

Item M32:在未来时态下开发程序

这个条款说的应该是怎么做到设计出一种能够尽量适应未来需求的软件。
未来时态的考虑只是简单地增加了一些额外约束:
1)、提供完备的类,即使某些部分现在还没有被使用。如果有了新的需求,你不用回过头去改它们。
2)、将你的接口设计得便于常见操作并防止常见错误。使得类容易正确使用而不易用错。例如,阻止拷贝构造和赋值操作,如果它们对这个类没有意义的话。防止部分赋值。
3)、如果没有限制你不能通用化你的代码,那么通用化它。例如,如果在写树的遍历算法,考虑将它通用得可以处理任何有向不循环图。

Item M33:将非尾端类设计为抽象类

Item M34:如何在同一程序中混合使用C++和C

C++与C语言的混用,就只有两种情况,要么C++中使用C语言,要么C语言中使用C++,需要注意下面几个方面:

名变换

名变换是C++中的概念,每个函数都有一个独一无二的名字。但C++中因为函数重载的原因,可能只是参数个数或参数类型不同,函数名是相同的,只使用函数名就无法表示它的独一无二。不同的编译器,有不同的名变换机制。
1)、C++中包含C语言
假设C++代码中引用了一个C库,有一个函数在C++文件中声明为:

void drawLine(int x1, int y1, int x2, int y2);

编译过后的obj文件,可能调用的函数名被编译器变换为:

xyzzy(a, b, c, d); // call to mangled function mame

但动态链接库里面以C风格编译出来的函数名仍然是:

drawLine(a, b, c, d);

那当进行obj链接的时候,因为找不到名为xyzzy的函数,就会报错。

要解决这个问题,需要一种方法来告诉C++编译器不要在这个函数上进行名变换。不期望对用其它语言写的函数进行名变换。

要禁止名变换,使用C++的extern ‘C’指示:

// declare a function called drawLine; don't mangle  its name
extern "C" void drawLine(int x1, int y1, int x2, int y2);

这样表示以C语言的方式进行编译,而不进行名变换。
如果有很多个不需要变换的函数,可以用大扣号合在一起:

extern "C" 
{
    void drawLine(int x1, int y1, int x2, int y2);
    void twiddleBits(unsigned char bits);
    void simulate(int iterations);
}

另外有些函数,可能同时提供给C语言和C++使用,则可以用宏__cplusplus区分:

#ifdef __cplusplus
extern "C" 
{
#endif
    void drawLine(int x1, int y1, int x2, int y2);
    void twiddleBits(unsigned char bits);
    void simulate(int iterations);
    ...
#ifdef __cplusplus
}
#endif

2)、C语言中使用C++
与前面同样的道理,也可能存在用C++写的库被C语言使用,那在库函数声明的时候,也是用关键字extern “C”。

extern "C" void simulate(int iterations);

也是禁止名变换的意思,但一般我在C++库中看到这种声明,把它认为是一个导出函数。

静态初始化

C++的代码中,有些代码在main函数执行前或执行后被执行。静态的类对象和定义在全局的、命名空间中的或文件体中的类对象的构造函数通常在main被执行前就被调用。这个过程称为静态初始化。同样,通过静态初始化产生的对象也要在静态析构过程中调用其析构函数;这个过程通常发生在main结束运行之后。
但是这可能是一种给人的假象,实际上编译器中仍然是首先调用的Main函数,只是在任何代码之前执行静态初始化,最后调用静态对象的析构函数。

int main(int argc, char *argv[])
{
    performStaticInitialization(); // generated by the  implementation

    the statements you put in main go here;

    performStaticDestruction(); // generated by the  implementation
}

这就需要,只要程序的任意部分是C++写的,就应该用C++写main()函数,否则无法调用初始化函数和析构函数。

这样可以把C语言写的main函数改名为realMain,C++的main中进行调用。

extern "C" int realMain(int argc, char *argv[]); // function in C
int main(int argc, char *argv[]) // write this in C++
{
    return realMain(argc, argv);
}

动态内存分配

简单说是就new和delete与mallco和free进行成对的使用。

数据结构的兼容性

C++和C语言中可能要传递数据,传递参数的结构应该是兼容C的,而不应该有C++中的语言特性。比如,不应该传递有虚函数这种类作为传递对象。

Item M35:让自己习惯使用标准C++语言

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值