C++ 固有的不可移植特性

  为了支持底层编程,C++定义了一些固有的不可移植的特性,即因机器而异的特性,当将含有不可移植特性的程序从一台机器转移到另一台机器上时,通常需要重新编写该程序。

1 位域

  类可以将其非静态数据成员定义成位域,在一个位域中含有一定数量的二进制位。当一个程序需要向其他程序或硬件设备传递二进制数据时,通常会用到位域。位域在内存中的布局是与机器相关的且位域的类型必须是整型或枚举类型。

typedef unsigned int Bit;
class File{
    Bit mode: 2;        //mode占2位
    Bit modified: 1;    //modified占1位
    Bit prot_owner: 3;  //占3位
    Bit prot_group: 3;  //占3位
    Bit prot_world: 3;  //占3位
    ...
}
public:
    enum modes{READ = 01, WRITE = 02, EXECUTE = 03};
    File &open(modes);
    void close();
    void write();
    bool isRead() const;
    void setWrite();

//使用位域
void File::write(){
    modified = 1;
    // ...
}
void File::close(){
    if(modified)
        ...
}
//通常使用内置的位运算符操作超过1位的位域
File &File::open(File::modes m){
    mode |= READ;       //按照默认方式设置READ
    if(m & WRITE)       //如果打开了READ和WRITE
    //按照读/写方式打开文件
    return *this;
}
//若一个类定义了位域成员,则它通常也会定义一组内联的成员函数来检查或设置位域的值
inline bool File::isRead() const{ return mode & READ; }
inline void File::setWrite(){ mode |= WRITE; }

注意2: 取地址运算符不能作用于位域,因此任何指针都无法指向类的位域。通常情况将位域设为无符号类型,存储在带符号类型中的位域的行为将因具体实现而定。

2 volatile限定符

  volatile关键字告诉编译器不对一些变量进行优化,它能保证对变量地址的稳定访问。常用于硬件程序、多线程中的变量共享等。volatile限定符用法和const相似,起到对类型额外修饰的作用,两者可同时使用。它们的区别是不能使用合成的拷贝/移动构造函数及赋值运算符初始化volatile对象或从volatile对象赋值。

volatile int v;     //v是一个volatile int
int *volatile x;    //x是一个volatile指针,指向int
volatile int *y;    //y是一个指针,指向volatile int
volatile int *volatile z;   //z是一个volatile指针,它指向一个volatile int
int *p = &v;        //错误,必须使用指向volatile的指针
y = &v;             //正确,y是一个指向volatile的指针
z = &v;             //正确,z是一个指向volatile的volatile指针

class foo{
public:
    foo(const volatile foo&);   //从一个volatile对象进行拷贝
    foo& operator=(volatile const foo&);  //将volatile对象赋值给非volatile对象
    foo& operator=(volatile const foo&) volatile; //将一个volatile对象赋值给volatile对象
}

3 extern “C”

  为在C++代码中支持C语言代码,extern "C"指出按照C语言进行编译。但要把C++代码和其他语言代码放在一起,需要有权访问该语言的编译器,并且这个编译器与当前编译器是兼容的。

//单语句链接指示
extern "C" size_t strlen(const char*);
//复合语句链接指示
extern "C"{
    int strcmp(const char*, const char*);
    char *strcat(char*, const char*);
}
//可以包含头文件,但不能添加在函数内部
extern "C"{
#include<string.h>
}

class smallInt{...};
class bigNum{...};
//c函数可以在c或者C++程序中调用,C++函数只能在C++程序中调用
extern "C" double calc(double);
extern smallInt calc(const smallInt&);
extern bigNum calc(const bigNum&);

References:

  • 《Primer c++》第五版
原创文章 38 获赞 13 访问量 4024

猜你喜欢

转载自blog.csdn.net/qq_36287943/article/details/105147412