什么是类?

类(Class) :是对具有相同 属性(数据)方法(行为)的一组对象的抽象描述

  • 类是 C++ 的核心特性之一,用于实现 面向对象编程(OOP)中的封装
  • 类是对象的蓝图,定义了对象的 属性(数据成员)行为(成员函数)

一个形象的例子:比如 “人类”,可以有姓名、年龄等属性,以及说话、行走等行为,在编程里就可据此定义一个 “人类” 的类。

怎么定义类?

代码语言:javascript

AI代码解释

class Person
{
public:
    void setAge(int a)
    {
        age = a;
    }
    int getAge()
    {
        return age;
    }
private:
    
};

C++使用 class关键字 定义,类中包含以下三部分的内容。 类的基本结构:关键的三个组成部分

  • 数据成员(属性):类的变量(int age;
  • 成员函数(方法):类的函数(void setAge(int a) 和 int getAge()
  • 访问修饰符
    • public:任何地方可访问
    • protected:类及其子类可访问
    • private:仅类内部访问(默认)
关于类需要注意什么?

下面博主挑选了四个关于“类”需要注意的事项,它们分别是关于:

  1. 类定义的语法规范
  2. 成员变量的命名约定
  3. structclass 的区别
  4. 类内定义的成员函数与内联

1. 类定义的语法规范

分号结尾:类定义结束时必须使用分号 ;,这是 C++ 语法的强制要求。

代码语言:javascript

AI代码解释

class MyClass // 类定义开始
{  
        
    // 成员...
        
};  // 分号不可省略!

2. 成员变量的命名约定

命名前缀 / 后缀:为避免成员变量与局部变量或函数参数重名,通常添加特殊标识:

代码语言:javascript

AI代码解释

class Person 
{
private:
    int m_age;          // m_前缀(Microsoft风格)
    std::string _name;  // 前缀(常见于开源项目)
    double salary_;     // 后缀(Google风格)
};

注意:C++ 标准并未强制要求此规则,具体风格需遵循团队或项目规范。

3. structclass 的区别

特性

struct

class

默认访问权限

public

private

设计哲学

数据聚合(POD, Plain Old Data)

封装复杂逻辑(OOP)

常见用途

轻量级数据容器、C 兼容结构

封装、继承、多态

示例对比

代码语言:javascript

AI代码解释

struct Point 
{  
    
    int x, y; // 默认public
    void move(int dx, int dy);  //注意:可定义函数
};
    
class Rectangle 
{  
    int width, height; // 默认private
public:
    int area() const 
    { 
        return width * height; 
    }
};

4. 类内定义的成员函数与内联

隐式内联:在类内部直接定义的成员函数会被编译器视为 inline 函数(但最终是否内联由编译器决定)

代码语言:javascript

AI代码解释

class Math 
{
public:
    int add(int a, int b) // 隐式内联
    {  
        return a + b;
    }
};

显式内联:若在类外定义函数,需显式使用 inline 关键字(通常在头文件中):

代码语言:javascript

AI代码解释

// Math.h
class Math 
{
public:
    int multiply(int a, int b);  // 声明
};
    
// Math.cpp
inline int Math::multiply(int a, int b) // 显式内联
{  
    return a * b;
}

注意事项

  • 内联函数的定义必须在每个调用它的翻译单元(.cpp 文件)中可见,因此通常直接放在头文件中。
  • 现代编译器会智能优化内联决策,即使未声明 inline,简单函数也可能被自动内联。
C++中的struct关键字有什么变化?

刚才我们有提到使用关键字struct来定义类,相比C++中的struct和C语言中的struct已经不太一样了吧,那两者又有什么区别呢?

代码语言:javascript

AI代码解释

include<iostream>
using namespace std;

/*
 * C++ 中对 struct 的升级:
 * 1. struct 现在是一个完全的类(class),内部可以定义成员函数
 * 2. struct 名称本身可以直接作为类型名使用(不再需要 typedef)
 */

// ------------------------- C 语言风格的链表节点 -------------------------
// C 中需要 typedef 简化类型名称
typedef struct SingleListNodeC
{
    int val;
    struct ListNodeC* next;  // C 中必须带 struct 关键字
}SLTNode;  // 通过 typedef 定义类型别名 LTNode

// ------------------------- C++ 风格的链表节点 -------------------------
// C++ 中 struct 本身就是类型名,且支持成员函数
struct SingleListNodeCPP
{
    // 成员函数:初始化节点
    void Init(int x)
    {
        val = x;         // 设置节点值
        next = nullptr;  // 初始化指针为空
    }

    // 成员变量
    int val;
    SingleListNodeCPP* next;  // 直接使用 SingleListNodeCPP 作为类型(无需 struct 关键字)
};

/*
 * 对比说明:
 * 1. C++ 的 struct 默认所有成员为 public(与 class 的唯一区别)
 * 2. 完全支持构造函数、析构函数等类特性
 * 3. 兼容 C 的语法,但更推荐 C++ 风格
 */

int main()
{
    // C 风格用法(兼容模式)
    SLTNode node_c;
    node_c.val = 10;
    node_c.next = NULL;

    // C++ 风格用法
    SingleListNodeCPP node_cpp;
    node_cpp.Init(20);  // 调用成员函数初始化

    return 0;
}

对比维度

C 语言风格 struct

C++ 风格 struct

类型定义方式

需用typedef定义类型别名简化使用,定义时节点类型前需加struct关键字

struct名称本身就是类型名,可直接使用,无需typedef和额外的struct关键字

成员函数支持

仅能定义数据成员,不支持成员函数

可定义成员函数,如案例中SingleListNodeCPP的Init函数用于初始化节点

访问权限默认值

无明确访问权限概念(类似 C++ 中public ,所有成员都可直接访问 )

默认成员访问权限为public(与class不同,class默认private )

使用类有哪些好处?

接下来我们就使用C++的类再次重新实现一下我们在《数据结构初阶》中实现的栈这种数据结构,直观的感受一下使用类实现和之前实现的区别:

代码语言:javascript

AI代码解释

#include<iostream>
#include<cstdlib>  
#include<cassert>  
using namespace std;

// 定义一个栈(Stack)类,基于动态数组实现
class Stack
{
public:

    /*-------------------------栈的“初始化”操作-------------------------*/
    /*
     * 初始化栈,默认初始容量为4
     * 参数n:可选参数,指定初始容量,默认为4
     */
    void Init(int n = 4)
    {
        //申请n个int大小的内存空间
        array = (int*)malloc(n * sizeof(int));

        // 检查内存是否申请成功
        if (array==nullptr)
        {
            perror("malloc申请空间失败");  
            return;
        }

        // 初始化栈的容量和栈顶指针
        capacity = n;
        top = 0;  //top指向下一个可插入的位置
    }


    /*-------------------------栈的“入栈”操作-------------------------*/
    void Push(int x)
    {
        // 这里应该添加扩容逻辑,当top == capacity时需要扩容
        // 当前实现没有扩容功能,会导致数组越界
        // 

        array[top++] = x;  // 元素放入数组,然后top指针后移
    }

    /*-------------------------栈的“获取栈顶元素”操作-------------------------*/
    int Top()
    {
        
        assert(top > 0); //断言检查栈是否为空

        return array[top - 1]; 
    }

    /*-------------------------栈的“销毁”操作-------------------------*/
    void Destroy()
    {
        free(array);         // 释放动态数组
        array = nullptr;     // 指针置空,防止野指针
        top = capacity = 0;  // 重置容量和栈顶指针
    }

private:
    
    /*---------------------成员变量---------------------*/
    int* array;   // 动态数组指针,存储栈元素
    int capacity; // 栈的容量
    int top;      // 栈顶指针(指向下一个可插入位置)
}; 

int main()
{
    Stack st;        // 创建栈对象
    st.Init();       // 初始化栈(使用默认容量4)
    st.Push(1);      // 压入元素1
    st.Push(2);      // 压入元素2

    // 输出栈顶元素(应该是2)
    cout << st.Top() << endl;

    st.Destroy();    // 销毁栈,释放资源

    return 0;
}

这里我们最能明显体会到的区别有以下三点:

维度

C语言实现

C++类实现

数据与操作

分离(结构体+独立函数)

整合(成员变量+成员方法)

实例表示

显式传递结构体指针(Stack*)

隐含this指针(st.Push())

访问控制

无封装(所有字段可被外部直接修改)

通过private保护关键数据

---------------类的实例化---------------

什么是类的实例化?

类的实例化:是指根据类的定义创建具体对象的过程。

  • 实例化后,对象会获得类中定义的成员变量(数据)和成员函数(行为),并占用实际的内存空间。

实例化的核心概念

  • 类(Class):是对象的蓝图或模板,仅定义结构,不占用内存。
  • 对象(Object):是类的具体实例,占用内存,存储实际数据。

类比

  • 类 ≈ 建筑设计图
  • 对象 ≈ 按设计图建造的房子

在面向对象编程中,一个类可以实例化出多个对象,这些实例化出的对象会占用实际的物理空间,用于存储类成员变量。 类与对象的关系就好比建筑设计图与实际建筑:建筑设计图详细规划了房屋的结构,如房间数量、空间布局、功能分区等,但它只是概念性的图纸,并不具备实体形态,无法供人居住或使用;只有依照设计图施工建造出实际的房屋,才能满足居住、办公等实际需求。 同理,类是对数据和行为的抽象描述,定义了成员变量和成员函数,但它本身并不占据物理内存,也无法存储实际数据,仅作为对象创建的模板。 而通过类实例化得到的对象,就像建造完成的房屋,会在计算机内存中分配实际的空间,用于存储类所定义的成员变量的值。

  • 例如:通过 “学生” 类可以实例化出张三、李四等具体学生对象,每个对象都有自己独立的存储空间,用于存放各自的姓名、年龄、成绩等成员变量数据,且不同对象的同一成员变量可以存储不同的值。
  • 多个对象之间相互独立,各自存储和管理自己的数据,却又共享类所定义的行为和操作规范,使得程序能够高效地处理复杂的现实场景。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐