C++Primer_Chap19_特殊工具与技术_List8_固有的不可抑制的特性_笔记

  为了支持底层编程,C++定义了一些固定的不可移植(nonportable)的特性。即因机器而异的特性

位域

  类可以将其(非静态)数据成员定义为位域(bit-field),在一个位域中含有一定数量的二进制位。位域在内存中的布局是与机器相关的。

  位域的类型必须是整型或者枚举类型。通常采用无符号类型保存一个位域。位域的声明形式是在成员名字之后竟跟一个冒号以及一个常量表达式,该表达式用于指定成员所占的二进制位数:

typedef unsigned int Bit;
class File {
    Bit mode: 2;
    Bit modified: 1;
    Bit prot_owner: 3;
    Bit prot_group: 3;
    Bit prot_world: 3;
public:
    //文件类型以8进制的形式表示
    enum modes { READ = 01, WRITE = 02, EXECUTE = 03 };
    File &open(modes);
    void close();
    void write();
    void isRead() const;
    void setWrite();
};

  取地址运算符(&)不能作用域位域。

void File::write()
{
    modified = 1;
    // ...
}

File &File::open(File::modes m)
{
    mode |= READ;    //默认设置为READ
    if( m & WRITE)
        //按照读/写方式打开文件
    return *this;
}

inline bool File::isRead() const
{
    return mode & READ;
}

inline bool File::setWrite() const
{
    mode |= WRITE;
}

volatile限定符

  直接处理硬件的程序常常包含这样的数据元素,它们的值由程序直接控制之外的过程控制。当对象的值可能在程序的控制或检测之外被改变时,应该将对象声明为volatile。关键字volatile告诉编译器不应对这样的对象进行优化。

volatile int display_register;
volatile Task *curr_task;
volatile int iax[max_size];    //数组的每个元素都是volatile
volatile Screen bitmapBuf;    //bitmapBuf的每个成员都是volatile

  const和volatile限定符互相没有什么影响。volatile和const类似:

  • 只有volatile的成员函数才能被volatile的对象调用
  • volatile限定符和指针之间也存在const和指针之间的关系(volatile指针、指向volatile对象的指针、指向volatile对象的volatile指针)

合成的拷贝对volatile对象无效 

  const和volatile的一个重要区别是我们不能使用合成的拷贝/移动构造函数及赋值运算符初始化volatile对象或从volatile对象赋值。因为合成的成员接受的形参类型是非volatile的常量引用。不能把非volatile引用绑定到一个volatile对象上。需要拷贝、赋值、移动,必须自定义操作

链接指示:extern "C"

  C++程序有时需要调用其他语言编写的函数,最常见的是调用C语言编写的函数。像所有其他名字一样,其他语言的函数名字也必须在C++中进行声明,该声明必须指出返回类型和形参列表。C++用链接指示(linkage directive)指出任意非C++函数所用的函数。

extern "C" size_t strlen(const char *);

extern "C" {
    int strcmp(const char*, const char*);
    char *strcat(char*, const char*);
}

指向extern "C"函数的指针

void (*pf1)(int);
extern "C" void (*pf)(int);
pf1 = pf;    //错误:类型不同

  指向C函数的指针与指向C++函数的指针时不一样的类型

链接指示对整个声明都有效

  当我们使用链接指示时,它不仅对函数有效,而且对作为返回类型和形参类型的函数指针也有效

//f1是一个C函数,形参是一个指向C函数的指针
extern "C" void f1(void(*)(int));

  因为链接指示同时作用域声明语句中的所有函数,所以如果希望给C++函数传入一个指向C函数的指针,必须使用类型别名

extern "C" typedef void FC(int);
//f2是一个形参为指向C函数的指针的C++函数
void f2(FC *);

对链接到C的预处理器的支持

  有时需要在C和C++中编译同一个源文件,为了实现这一目的,在编译C++版本的程序时预处理器定义__cplusplus:

#ifdef __cplusplus
//正确:我们正在编译C++程序

extern "C"
#endif
int strcmp(const char*, const char*);

重载函数与链接指示

  链接指示与重载函数的相互作用依赖于目标语言。如果目标语言支持重载,则为该语言实现链接指示的编译器也可能支持重载这些C++的函数。

  C语言不支持函数重载,因此一个C链接指示只能用于说明一组重载函数中的某一个。

你可能感兴趣的:(C++)