大话C++:第11篇 类的定义与封装

1 类的定义

在C++中,类的定义通常使用class关键字开始,后面紧跟类的名称。类可以包含数据成员(变量)和成员函数(方法)。

在C++中,类可以更加详细地展开,包括数据成员(变量)的声明、成员函数的声明与定义、构造函数、析构函数、内联成员函数、静态成员、友元函数等。类定义的语法格式

cpp 复制代码
// ClassName类名
class ClassName 
{
public:
    // 公共构造函数
    ClassName();                      // 默认构造函数
    ClassName(const ClassName& other); // 拷贝构造函数
    ~ClassName();                     // 析构函数

    // 公共成员函数(包括内联函数)
    void publicFunction();
    void anotherPublicFunction() const; // const成员函数
    static void staticPublicFunction(); // 静态成员函数

    // 公共成员变量(通常不推荐,因为破坏了封装性)
    int publicVariable;

    // 友元函数和友元类
    friend void friendFunction(ClassName& obj);
    friend class FriendClass;

protected:
    // 受保护成员函数
    void protectedFunction();

    // 受保护成员变量
    int protectedVariable;

private:
    // 私有成员函数
    void privateFunction();

    // 私有成员变量
    int privateVariable;

    // 私有静态成员变量
    static int privateStaticVariable;

    // 私有静态成员函数
    static void privateStaticFunction();

    // 类内定义成员函数(内联函数)
    inline void inlineFunction() {
        // 函数体
    }

    // 类的嵌套类
    class NestedClass {
        // NestedClass 的定义
    };
};

其中,

  • 构造函数和析构函数用于对象的初始化和清理。

  • 成员函数可以是公共的、受保护的或私有的。

  • 静态成员(函数和变量)属于类本身,而不是类的任何特定对象。

  • 友元函数和友元类可以访问类的私有和保护成员。

  • 内联函数通过在调用点插入函数体的复制品来提高执行速度,适合函数体简短且调用频繁的情况。

  • 嵌套类是在另一个类内部定义的类。

类的定义通常放在头文件中,类的实现放在源码文件cpp。例如,学生的定义与实现

  • student.h学生类的定义
cpp 复制代码
// student.h
#ifndef __STUDENT_H__
#define __STUDENT_H__

#include <string>

class Student 
{
public:
    // 构造函数
    Student(const std::string& name, int age, int num);
    // 析构函数
    ~Student();

    // 公共成员函数
    void DisplayInfo() const;

	// 获取成员变量的函数
    // 获取姓名
    inline std::string GetName() const;
    // 获取年龄
	inline int GetAge() const;
	// 获取学号
    inline int GetNum() const;
    
    // 设置成员变量的函数
    // 设置姓名
    inline void SetName(const std::string& name);
    // 设置年龄
    inline void SetAge(const int age);
    // 设置学号
    inline void SetNum(const int num);


private:
    // 私有成员变量
    std::string _name;	// 姓名
    int _age;			// 年龄
    int _num;			// 学号
};

#endif // __STUDENT_H__
  • student.cpp学生类的实现
cpp 复制代码
// student.cpp
#include "student.h"
#include <iostream>

// 构造函数
Student::Student(const std::string& name, int age, int num) 
    : _name(name), 
	  _age(age), 
	  _num(num)
{
    std::cout << "Student构造函数" << std::endl;
}

// 析构函数(在这个简单的例子中,析构函数是空的)
Student::~Student() 
{
    std::cout << "Student析构函数" << std::endl;
}

// 显示学生信息
void Student::DisplayInfo() const 
{
    std::cout << "该学生姓名:" << _name 
        << ",年龄:" << _age 
        << ",学号:" << _num 
        << std::endl;
}

// 获取学生姓名
std::string Student::GetName() const
{
    return _name;
}

// 获取年龄
int Student::GetAge() const
{
	return _age;    
}

// 获取学号
int Student::GetNum() const
{
    return _num;
}

// 设置姓名
void Student::SetName(const std::string& name)
{
    _name = name;
} 

// 设置年龄
void Student::SetAge(const int age)
{
    _age = age;
}

// 设置学号
void Student::SetNum(const int num)
{
    _num = num;
}
  • main.cpp学生对象的定义及使用
cpp 复制代码
// main.cpp
#include <iostream>
#include "student.h"

int main()
{
    // 创建学生对象
    Student student("Jack", 25);

    // 调用成员函数
    student.DisplayInfo();
    std::cout << "该学生对象的名字: " << student.GetName() << std::endl;

    // 修改学生年龄
    student.SetAge(22);

    // 再次调用成员函数
    student.DisplayInfo();

    return 0;
}

2 类的封装

C++ 类的封装是面向对象编程中的一个核心概念,它指的是将数据(成员变量)和行为(成员函数)结合在一起的机制,并隐藏内部实现细节,只暴露出一个可以被外界访问和使用的接口。封装可以提高安全性和易于维护,因为它限制了对类内部数据的直接访问,只允许通过类提供的成员函数来操作数据。

为了实现封装,C++提供了访问修饰符(publicprivateprotected)来控制类成员的访问权限。访问修饰符对类、派生类及对象具有不同的访问权限,如下表所示:

访问修饰符 类内部 派生类内部 对象(外部) 示例
public 可访问 可访问 可访问 成员在类的外部和内部都可以被访问。
private 可访问 不可访问 不可访问 成员只能在类的内部被访问,对象和派生类都无法直接访问
protected 可访问 可访问 不可访问 成员在类的内部和派生类中可以被访问,但对象无法直接访问
cpp 复制代码
#include <iostream>

class Person 
{
public:
    void SetName(const std::string& name) { // 公有成员函数
        _name = name;
    }

    std::string GetName() const 
    { 
        // 公有成员函数
        return _name;
    }
    
protected:
    // 受保护成员函数
    void SetAge(int age) 
    {
        _age = age;
    }    
    
protected:
    // 受保护成员变量
    int _age; 

private:
    // 私有成员变量 
    std::string _name;    
};

int main()
{
    Person person;

    // 对象无法直接访问私有成员
    // person._name = "Alice";

    // 对象可以访问公有成员函数
    person.SetName("Jack");
    std::cout << person.GetName() << std::endl;

    // 对象无法直接访问受保护成员
    // person._age = 10; // 错误:受保护成员无法访问

    return 0;
}

3 类的访问修饰符

在C++中,类的访问修饰符主要用于控制类成员(包括数据成员和成员函数)的访问权限。这些修饰符主要有四种:publicprotectedprivate和默认的default。其中,

  • public(公共访问修饰符)

    • 访问权限:最高级别的访问权限。

    • 作用:允许类的任何对象以及任何其他代码访问该类的成员(无论是数据成员还是成员函数)。

    • 使用场景:通常用于提供类的外部接口,即允许外部代码调用的成员函数或访问的数据成员。

  • protected(受保护的访问修饰符)

    • 访问权限:次高级别的访问权限。

    • 作用:允许类的对象、派生类(子类)以及类的内部代码访问该类的成员。

    • 使用场景:通常用于实现继承时,在基类中定义一些需要被子类访问但不需要被外界访问的成员。

  • private(私有的访问修饰符)

    • 访问权限:最低级别的访问权限。

    • 作用:只允许类的内部代码访问该类的成员。

    • 使用场景:通常用于隐藏类的内部实现细节,确保数据的封装性。

  • default(默认访问修饰符)

    • 访问权限:包(package)级别的访问权限。

    • 作用:允许同一包(package)中的其他类访问该类的成员,但不允许包外的类访问。

表格形式总结一下,详见下表:

访问修饰符 访问权限 类内部 派生类内部 类的对象 同包其他类 说明
public 公有 可访问 可访问 可访问 可访问 允许外部访问
protected 受保护 可访问 可访问 不可访问 不可访问 允许派生类访问
private 私有 可访问 不可访问 不可访问 不可访问 仅允许类内部访问

注意 :在C++中,没有明确的default关键字来表示包私有访问,这里的default仅用于类比,代表类内部和同一包内其他类可以访问,但对象和包外类无法访问。在C++中,如果一个成员没有被显式声明为publicprotectedprivate,那么它的访问级别就是private

相关推荐
芥末虾2 分钟前
【优选算法】KMP模式匹配算法 {算法介绍;算法原理:核心原理,如何求next数组;代码实现}
c语言·c++·算法·kmp·字符串模式匹配
薔薇十字8 分钟前
【代码随想录day36】【C++复健】1049. 最后一块石头的重量 II ; 494. 目标和 ;474.一和零
c++·算法·leetcode
阿阿越16 分钟前
数据结构进阶(C++) -- AVL树的实现
数据结构·c++
gma99921 分钟前
【shell编程】函数、正则表达式、文本处理工具
linux·c++·正则表达式·bash
向前看-38 分钟前
青训营刷题笔记17
c++·笔记·算法
儒雅芝士41 分钟前
Ros2 操作指令记录
c++·python·机器人
rolt1 小时前
[pdf,epub]162页《分析模式》漫谈合集01-35提供下载
ddd·架构师·uml·领域驱动设计·面向对象
寒雒1 小时前
【C++】static修饰的“静态成员函数“--静态成员在哪定义?静态成员函数的作用?
c++
重生之我是数学王子1 小时前
QT 实现仿制 网络调试器(未实现连接唯一性) QT5.12.3环境 C++实现
开发语言·c++·qt
极地星光2 小时前
C++自动化测试:GTest 与 GitLab CI/CD 的完美融合
c++·ci/cd·gitlab