40、C++ Primer 4th笔记,特殊工具与技术,不可移植特征
1、程序可以从一个机器容易得移植到其他机器,则称此程序是可移植的。C语言是可移植的。
当然,C语言也定义了一些固有的不可移植的特性:
1)算术类型的大小随机器不同而变化。
C++另外两个从C语言继承来的不可移植的特性:位域和volatile限定符(这两个特性使与硬件的直接通信更容易),链接批示(使得可以链接到用其他语言编写的程序)。
2、位域
位域(bit-field):来保存选定的位数。当程序需要将二进制数据传递给另一个程序或硬件设备的时候,通常使用位域。位域在内存中的布局是机器相关的。位域必须是整形数据类型,可以是signed或unsigned。
http://www.cnblogs.com/mydomain/archive/2010/09/25/1834891.html
http://m.cnblogs.com/73456/1834891.html
最好将位段设为unsigned类型。存储在signed类型中的位段的行为由实现定义。
地址操作符&不能应用于位域,所以不可能有引用类位域的指针,位域也不能是类的静态成员。
示例代码
#include <iostream> #include "string" using namespace std; typedef unsigned int Bit; class File { public: Bit mode : 2; Bit modified : 1; //... public: void write(); void close(); int isRead() { return mode & READ; } int isWrite() { return mode & WRITE; } }; void File::write() { modified = 1; //... } void File::close() { if (modified) //...save contents } enum {READ = 01, WRITE = 02}; //File Modes int main() { File myFile; myFile.mode |= READ; if (myFile.mode & READ) cout << "//..." << endl; return 1; }
3、volatile限定符
1)当可以用编译器的控制或检测之外的方式改变对象值的时候,应该将对象声明为volatile。关键字volatile是给编译器的指示,指出对这样的对象不应该执行优化。如程序中包含由系统时钟更新的变量。
2)用与const限定符的相同的方式使用volatile限定符。volatile对象只能调用volatile成员函数。
3)对待 const 和 volatile 的一个重要区别是,不能使用合成的复制和赋值操作符从 volatile 对象进行初始化或赋值。合成的复制控制成员接受 const形参,这些形参是对类类型的 const 引用,但是,不能将 volatile 对象传递给普通引用或 const 引用。
如果类希望允许复制volatile对象,或者类希望允许从volatile操作数或对volatile操作数进行赋值,它必须定义自己的复制构造函数和/或赋值操作符版本。
可以定义const volatile限制的变量。
4、链接指示:extern "C"
编译器一般必须产生不同的代码来调用其他语言编写的函数。C++ uses
linkage directives to indicate the language used for any non-C++ function.
1)链接指示有两种形式:单个的或复合的。链接指示不能出现在类定义或函数定义的内部,它必须出现在函数的第一次声明上。
示例代码
// illustrative linkage directives that might appear in the C++ header <cstring> // single statement linkage directive extern "C" size_t strlen(const char *); // compound statement linkage directive extern "C" { int strcmp(const char*, const char*); char* strcat(char*, const char*); }; extern "C" { #include "string.h" // C functions that manipulate C-style strings }; // the calc function can be called from C programs extern "C" double calc(double dparm) { /* ... */ }
2)可以将多重声明应用于整个头文件。链接指示可以嵌套。
3)通过对函数定义使用链接指示,使用其他语言编写的程序可以使用C++函数。
4)在同一源文件中使用C和C++。
当编译C++时,自动定义预处理器名字__cplusplus。
示例代码
#ifdef __cplusplus extern "C" #endif int strcmp(const char*, const char*);
5)The C language does not support function overloading, so it should not be a
surprise that a linkage directive can be specified only for one C function in a set of
overloaded functions. It is an error to declare more than one function with C linakage
with a given name。
6)extern "C" 函数的指针
extern "C" void (*pf)(int);
C函数的指针与C++函数的指针具有不同的类型,不能将C函数的指针初始化或赋值为C++函数的指针(反之)。
7)Because a linkage directive applies to all the functions in a declaration, we must
use a typedef to pass a pointer to a C function to a C++ function:
// FC is a pointer to C function
extern "C" typedef void FC(int);
// f2 is a C++ function with a parameter that is a pointer to a C function
void f2(FC *);
5、小结
1)局部类,是局部于函数而定义的非常简单的类。局部类的所有成员必须定义在类定义体中,局部类没有静态数据成员。局部类不能访问外围函数中定义的局部变量,它们可以使用外围函数中定义的类型名,静态变量,枚举成员。
2)allocator标准库类,支持原始未构造内存的类特定的分配。
3)联合的成员必须为简单类型:内置类型,复合类型,没有定义构造函数、析构函数或赋值操作符的类类型。联合可以有成员函数,包括构造函数,析构函数。联合不能作基类作用。