🍅不可移植的特性
2022-6-25
| 2023-8-2
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 

 
为了支持底层编程(low-level programming)C++ 定义了一些固有不可移植的特性(nonportable features)。不可移植的特性是特定于机器的,使用了不可移植的特性通常需要在换了平台时重新对这部分进行编程。算术类型的长度在不同机器之间不一样就是一个不可移植的特性。
 

位域

类可以将数据成员定义为位域(bit-field),位域包含特定的二级制位数,它们通常用于传递二进制数据给另外一个程序或者给硬件设施。位域的内存布局是与机器相关的。
位域必须是整数类型或者枚举类型。通常使用的类型是unsigned类型,这是由于signed位域的行为是由具体实现决定的。通过在成员名后加冒号和常量表达式指定成员所占的二进制位数:
位域可能被会打包到一个整数值中去以压缩存储,至于是如何实现的标准并没有规定。地址操作符(&)不能用于位域字段,所以位域字段是没有指针的。
 
使用位域
访问位域的方式与普通的数据成员一样:
 
通常使用内置的位运算符操作超过1位的位域:
 
如果一个类定义了位域成员,则它通常也会定义一组内联的成员函数以检验或设置位域的值:
 

volatile 限定符

volatile并不是一个有具体语义的关键字,而是由编译器实现决定的。硬件编程通常会有数据成员的值是外部进程决定的,如:变量是系统时钟。当对象的值会被程序外部改变时,应该将其声明为volatile的。volatile指示编译器不要对这种对象进行优化。
 
一些volatile变量的定义:
volatileconst之间没有任何交互,所以可以同时定义volatileconst而不相互影响。
 
类可以定义volatile成员函数,volatile成员函数只能在volatile对象上调用。volatile与指针的相互作用和const与指针之间的相互作用是一样的,即指针本身是 volatile或者指向volatile对象的对象,或者两者都是volatile的:
const一样,只能将volatile对象的地址赋值给指向volatile的指针,只能将volatile对象用于初始化 volatile 引用。
 
合成拷贝不会被运用于volatile对象
constvolatile的一个最大的不同在于合成的拷贝控制成员不能以volatile对象为源,即不可以将其作为初始值或者赋值的右边操作数。如果想要这么做,必须手动定义对应的操作函数。例如,可以将形参类型指定为const volatile引用,这样就可以进行拷贝或赋值操作了:
拷贝volatile对象是否有意义?这个问题与具体的实现有关
 
 

链接指令:extern "C"

C++有时会调用C语言中书写的函数,想要这么做必须首先声明这些函数。由于C++中的函数与C的函数在二进制文件中的符号是不一样的。所以得使用链接指令(linkage directives)来告知C++这个函数是用不同的语言写成的。
 
声明一个非 C++ 函数
链接指令有两种形式:单行和复合形式。链接指令不能出现在类和函数定义中。相同的连接指令必须出现在一个函数的所有声明处。如:
第一种形式就是 extern 关键字后跟一个字符串,后跟一个普通的函数声明。第二种形式则将所有的函数声明放在一个括弧中。
 
还有一种用法是将 #include 放在链接指令中,如:
这样string.h头文件中所有函数都被认为是 C 语言中的函数。链接指令是可以嵌套的,如果头文件中包含了一个函数有自己的链接指令,那个函数的链接将不会受到影响。
 
指向 extern "C" 函数的指针
函数的定义语言是函数类型的一部分,所以函数指针也要告知链接指令:
以上pf被认为是一个 C 函数的指针。C函数的指针与C++函数的指针是不同的类型,所以不能将C++函数用于初始化C函数指针(反之亦然)。如:
链接指令被运用于整个整个声明,如
如上语句中,f1 和指针都是 C 函数。如果仅仅指向然指针是 C 函数则需要用到类型别名,如:
 
将 C++ 函数导出给其它函数
通过在函数定义上运用链接指令,可以将 C++ 函数导出给 C 语言:
当编译器翻译代码时,它会将生成 C 语言的代码。
需要注意的是跨语言的参数和返回值类型是受限的,比如不能传递 nontrivial C++ 类给 C 语言的程序,C 语言不知道构造函数、析构函数和其它与类相关的操作。
 
预处理器的支持
C++ 编译器定义了宏 __cplusplus ,所以可以用如下方式来加入链接指令。如:
重载函数和链接指令
C 语言不支持函数重载,所以只能将重载集合中的一个函数暴露给 C 语言:
如果重载函数集中有一个是 C 函数,那么其他所有函数必须是 C++ 函数:
C版本的calc可以在CC++中调用,而其它的函数只能在C++中调用,声明的顺序是不重要的。
  • C++
  • 命名空间包装器
    目录