C++ 类、结构体与共用体详解:语法特性与内存布局

Mia
Mia
发布时间:2026-10-16 | 6人浏览过
原创

C++ 语言中类(class)、结构体(struct)和共用体(union)是构建数据和行为的核心容器。类用于实现面向对象编程,支持封装、继承和多态;结构体侧重于数据聚合,但在 C++ 中具备成员函数能力;共用体则通过共享同一块内存来实现类型转换或节省空间。理解它们的默认权限、生命周期管理及内存布局,是编写高效 C++ 程序的基础。

一、类 class:面向对象的基础

类是 C++ 面向对象特性的核心,是对具有相同属性和行为的对象的抽象。与 C 语言不同,C++ 的类支持访问控制、继承和多态机制。虽然 C++ 没有独立的“接口”关键字,但可以通过纯虚函数模拟接口功能,且支持多继承。

第 1 步:定义类的结构与成员访问权限

类由头文件和实现文件组成,需明确定义私有、公共和保护成员。访问修饰符决定了外部对类内部数据的可见性:

  • private:私有成员,仅类自身及友元可访问,外部不可见。
  • public:公共成员,任何地方均可访问。
  • protected:保护成员,类自身及子类可访问,外部不可见。

第 2 步:实现构造函数与析构函数

构造函数用于对象创建时的初始化,析构函数用于对象销毁前的资源清理。两者的名称必须与类名一致(析构函数加波浪号),且无返回类型。

class Fruit {
    private:
        int count;
    public:
        // 声明构造函数
        Fruit();
        // 声明析构函数
        ~Fruit();
        // 内联定义的成员函数
        int getCount() { return count; }
};

// 在类外部实现构造函数
Fruit::Fruit() {
    std::cout << "Create fruit" << std::endl;
}

// 在类外部实现析构函数
Fruit::~Fruit() {
    std::cout << "Fruit deleted" << std::endl;
}

第 3 步:使用友元函数突破访问限制

友元函数(Friend Function)不属于类的成员,但被授权访问类内部的 private 和 protected 成员。通常在类定义中使用 friend 关键字声明。

#include <iostream>
using namespace std;

class Fruit {
    private:
        int count = 0;
    public:
        Fruit();
        ~Fruit();
        // 声明友元函数
        friend void printCount(Fruit &ft);
};

// 友元函数定义在类外部
void printCount(Fruit &ft) {
    // 直接访问私有成员
    cout << ft.count << endl;
}

int main() {
    Fruit f;
    printCount(f); // 输出 0
    return 0;
}

第 4 步:实现继承、虚函数与多态

C++ 支持公有继承(public)及多继承。为了实现运行时多态,需要使用虚函数(Virtual Function)。若父类存在未实现的虚函数(纯虚函数),该类变为抽象类,不能实例化,必须通过子类调用。

  • 普通函数调用:根据指针/引用类型决定调用哪个版本(静态绑定)。
  • 虚函数调用:根据实际指向的对象类型决定(动态绑定)。
  • 纯虚函数:形如 virtual void func() = 0;,强制子类重写。

以下示例展示了从抽象基类到派生类的覆盖过程:

class Fruit {
    public:
        // 抽象方法,子类必须实现
        virtual void show() = 0;
        
        // 普通虚方法,子类可选重写
        virtual void name() {
            cout << "Base Name" << endl;
        }
};

class Apple : public Fruit {
    public:
        void show() override {
            cout << "This is an Apple" << endl;
        }
        void name() override {
            cout << "Apple Name" << endl;
        }
};

int main() {
    Apple apple;
    apple.show(); // 调用子类重写的纯虚函数
    apple.name(); // 调用子类重写的虚函数
    return 0;
}

第 5 步:多继承的实现

C++ 允许一个类同时继承多个父类,这在其他主流 OOP 语言中较少见。需注意多重继承可能引发的钻石问题(可通过虚拟继承解决)。

class A { /* ... */ };
class B { /* ... */ };

class C : public A, public B {
    // C 同时拥有 A 和 B 的成员
};

二、结构体 struct:数据聚合与对象化的桥梁

在 C++ 中,struct 不仅可以用作 C 风格的数据集合,还可以像类一样包含成员函数、构造函数及访问控制符。它是从 C 过渡到 C++ 面向对象编程的重要过渡形态。

第 1 步:基本定义与初始化

与 class 最大的区别在于:struct 的默认访问权限是 public,而 class 的默认权限是 private。这使得 struct 更适合作为纯数据载体(类似 Java 的 POJO/Bean)。

// 基本结构体定义
struct Book {
    string name;
    int id;
    long ISBN;
} book1, book2; // 可直接在此处定义实例

// 结构体初始化(列表初始化)
Book book3 = {"C++ Primer", 1, 123456789};

第 2 步:结构体的进阶操作

可以使用类型别名简化声明,或使用指针进行内存管理。注意,结构体也可以拥有方法和继承能力。

typedef struct {
    int id;
    string title;
} Ebook;

// 指针操作
Ebook *ptr = &ebook_instance;
ptr->id = 100;

// 结构体继承
struct SpecialBook : public Book {
    string publisher;
    void printInfo() { cout << name << endl; };
};

三、共用体 union:内存共享的特殊结构

共用体(Union)是一种特殊的数据类型,其所有成员共享同一段内存空间。这意味着在同一时刻,共用体只能存储其中一个成员的值。对其一成员赋值会破坏其他成员的数据,常用于节省内存或进行底层类型转换。

第 1 步:共用体的定义与行为验证

共用体的大小取决于其最大成员的大小。当写入新成员时,旧成员的二进制数据会被覆盖或reinterpret,因此读取旧成员通常得到无意义值。

union Data {
    int i;
    double d;
    char str[20];
};

int main() {
    Data data;
    data.i = 10;       // 占用4字节整数空间
    cout << data.i << endl; // 正常输出
    
    strcpy(data.str, "Hello"); // 现在覆盖了前面的整数
    cout << data.str << endl; // 正常输出字符串
    // cout << data.i << endl; // 此时读取 i 可能产生错误结果
    return 0;
}

第 2 步:共用体的限制与规范

C++ 标准对共用体的限制比 C 更严格,但也赋予了更多功能:

  • 访问控制:默认为 public。
  • 成员要求:不能包含引用类型成员;不能含有虚函数;不能作为基类被继承。
  • 匿名共用体:可以在结构体内定义匿名共用体,使其成员直接暴露在父作用域中,但不能包含受保护(protected)或私有(private)成员。
  • 全局共用体:若为匿名共用体,则必须是 static 存储期。

共用体常嵌套在结构中,用于处理互斥的数据场景:

struct Record {
    string name;
    union {
        int score_int;
        float score_float;
    }; // 匿名共用体
};

四、C 与 C++ 中 Struct 的关键区别

理解这些差异有助于在不同语言环境下正确移植代码:

  • 成员函数: C 结构体不能有函数成员;C++ 结构体可以。
  • 封装性: C 结构体无访问修饰符;C++ 结构体支持 public/private/protected。
  • 继承: C 不支持结构体继承;C++ 结构体支持继承。
  • 实例化: C 中定义变量时必须加 struct 前缀(如 struct Book b);C++ 中可以直接写 Book b。

以上就是 C++ 类(class)、结构体(struct)和共用体(union)的详细内容,更多关于 C++ 面向对象编程与内存管理的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表