在 C++ 中,. 运算符用于访问对象的成员,而 -> 运算符用于访问指针指向的对象的成员。

换句话说,. 用于对象本身,-> 用于指向对象的指针。

例如,如果你有一个对象 obj 和一个指向对象的指针 ptr,你可以用 obj.member 来访问成员,也可以用 ptr->member 来访问同样的成员。

#include <iostream>

class Example {
public:
    void display() {
        std::cout << "Hello, World!" << std::endl;
    }
};

int main() {
    Example obj;           // 创建对象
    Example* ptr = &obj;  // 创建指向对象的指针

    obj.display();        // 使用 . 访问成员
    ptr->display();       // 使用 -> 访问成员

    return 0;
}

在 C++ 中,union 类型的成员访问也可以使用 -> 运算符。与类或结构体类似,union 也可以包含多个成员。使用 -> 运算符时,首先需要有一个指向 union 的指针。

以下是一个示例代码,展示如何在 union 中使用 -> 运算符:

#include <iostream>

union Data {
    int intValue;
    float floatValue;
    char charValue;
};

int main() {
    Data data;               // 创建 union 对象
    Data* ptr = &data;      // 创建指向 union 的指针

    // 通过指针访问 union 的成员
    ptr->intValue = 42;     // 使用 -> 设置值
    std::cout << "Integer: " << ptr->intValue << std::endl;

    ptr->floatValue = 3.14; // 使用 -> 设置另一个值
    std::cout << "Float: " << ptr->floatValue << std::endl;

    // 注意:union 只能安全地使用最后一次设置的成员
    std::cout << "Char: " << ptr->charValue << std::endl; // 结果未定义

    return 0;
}

在这个示例中,我们创建了一个 union 类型的 Data,并通过指针 ptr 使用 -> 运算符访问和设置成员。注意,因为 union 只能安全地使用最后设置的成员,使用未初始化的成员可能导致未定义行为。

扩展:

unionstruct 的主要区别在于内存分配和成员访问方式:

  1. 内存分配struct 中的每个成员都有自己的内存空间,所有成员的内存总和决定了 struct 的大小。而 union 只为最大成员分配内存,因此其大小等于最大成员的大小。

  2. 成员访问:在 struct 中,可以同时使用所有成员;而在 union 中,任何时刻只能使用一个成员,修改一个成员会影响其他成员的值。

例如:

struct MyStruct {
    int a;
    float b;
};

union MyUnion {
    int a;
    float b;
};

在这里,MyStruct 可以同时存储 ab 的值,而 MyUnion 只能存储 ab 中的一个。

union 通常用于以下场合:

节省内存:当一个数据结构中的多个成员在同一时间只需要存储一个值时,使用 union 可以节省内存。例如,图形程序中的颜色值可能有多种表示形式(RGB、HSV等),但在任何时候只需存储一种形式。

类型转换:在需要不同类型之间的转换时,union 可以方便地将一个值视为不同的类型。例如,网络通信协议中可能需要将不同类型的数据打包和解包。

硬件编程:在嵌入式系统中,union 常用于映射硬件寄存器,使得可以通过不同的数据类型访问同一块内存。

数据解析:在解析复杂数据结构(如文件格式或协议)时,union 可以表示多种可能的格式,便于处理不同类型的数据。