zoukankan      html  css  js  c++  java
  • C++ Primer 笔记——固有的不可移植的特性

    1.为了支持底层编程,C++定义了一些固有的不可移植的特性,所谓不可移植特性是指因机器而异的特性。

    2.一个位域中含有一定数量的二进制位,位域在内存中的布局是机器相关的。位域的类型必须是整型或枚举类型,因为带符号位位域的行为是由具体实现确定的,所以在通常情况下我们使用无符号类型保存一个位域。

    typedef unsigned int Bit;
    class test
    {
        Bit A : 2;    // A占2位
        Bit B : 1;    // B占1位
        Bit C : 3;    // C占3位
    };

    如果可能的话,在类的内部连续定义的位域压缩在同一整数的相邻位,从而提供存储压缩。这些是与机器相关的。

    3.取地址运算符不能作用于位域,因此任何指针都无法指向类的位域。

    4.访问位域的方式:

    typedef unsigned int Bit;
    class test
    {
    public:
        Bit A : 2;    // A占2位
        Bit B : 1;    // B占1位
        Bit C : 3;    // C占3位
    };
    
    test t;
    
    t.A |= 0xFF;    // A=3
    t.B = 1;        // B=1
    t.C &= 0x00;    // C=0


     

    5.volatile表示对象的值可能在程序的控制或检测之外被改变,并告诉编译器不应该对这样的对象进行优化。voilatile起到对类型额外修饰的作用。

    class test{};
    
    volatile int i;            // 该int值可能发生改变
    volatile int* p;        // p指向一个volatile对象
    volatile int arr[2];    // arr的每个元素都是volatile
    volatile test t;        // t的每个成员都是volatile

    6.const和volatile限定符互相没什么影响,某种类型可能既是const的也是volatile的,此时它同时具有二者的属性。

    7.就像一个类可以定义const成员函数一样,它也可以将成员函数定义成volatile的,只有volatile的成员函数才能被volatile的对象调用。

    8.和const一样,我们只能将一个volatile对象的地址赋值给一个指向volatile的指针,只有当某个引用是volatile的时,我们才能使用一个volatile对象初始化该引用。

    volatile int i;                // i是一个volatile int
    int *volatile ip;            // ip是一个volatile指针,指向int
    volatile int* p;            // p是一个指针,指向volatile int
    volatile int *volatile vp;    // vp是一个volatile指针,它指向一个volatile int
    
    int *p1 = &i;    // 错误,必须使用只想volatile的指针
    p = &i;            // 正确
    vp = &v;        // 正确


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

    10.C++ 使用链接指示指出任意非C++函数所用的语言。想要把C++代码和其他语言编写的代码放在一起使用,要求我们必须有权访问该语言的编译器,并且这个编译器与当前的C++编译器是兼容的。

    11.链接指示不能出现在类定义或函数定义的内部。同样的链接指示必须在函数的每个声明中都出现。

    extern "C" size_t strlen(const char*);    // 单语句链接指示
    
    extern "C"    // 复合语句链接指示
    {
        int strcmp(const char&, const char*);
        char *strcat(char*, const char*);
    }


    12.多重声明的形式可以应用于整个头文件。头文件中所有普通函数声明都被认为是由链接指示的语言编写的,链接指示可以嵌套,因此如果头文件包含自带链接指示的函数,则该函数的链接不受影响。

    extern "C"    
    {
        #include <string.h>
    }


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

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


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

    extern "C"    typedef void func(int);
    void f(func *);


    15.通过使用链接指示对函数进行定义,我们可以令一个C++函数在其它语言编写的程序中可用。但是要注意类型限制。

    extern "C"    int add(int) {}        // add 函数可以被C程序调用


    16.有时候需要在C和C++中编译同一个源文件,我们可以使用预处理定义__cplusplus。

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


    17.链接指示与重载函数的相互作用依赖于目标语言。如果目标语言支持重载函数,则为该语言实现链接指示的编译器很可能也支持重载这些C++的函数。如果在一组重载函数中有一个是C函数,则其余的必定都是C++函数。

  • 相关阅读:
    linux学习笔记--文件
    linux学习笔记——基础命令
    nginx实现动静分离
    keepalived+nginx高可用负载均衡环境搭建
    keepalived衡环境搭建
    redis配置文件redis.conf说明
    基于sentinel 的redis集群环境搭建
    jdk动态代理
    spring的事物实现
    Linux用户配置
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/7467075.html
Copyright © 2011-2022 走看看