大话C++语言:类的定义与封装

1 类的定义

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

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

// 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学生类的定义
// 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学生类的实现
// 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学生对象的定义及使用
// 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++提供了访问修饰符(public、private、protected)来控制类成员的访问权限。访问修饰符对类、派生类及对象具有不同的访问权限,如下表所示:

访问修饰符

类内部

派生类内部

对象(外部)

示例

public

可访问

可访问

可访问

成员在类的外部和内部都可以被访问。

private

可访问

不可访问

不可访问

成员只能在类的内部被访问,对象和派生类都无法直接访问

protected

可访问

可访问

不可访问

成员在类的内部和派生类中可以被访问,但对象无法直接访问

#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++中,类的访问修饰符主要用于控制类成员(包括数据成员和成员函数)的访问权限。这些修饰符主要有四种:public、protected、private和默认的default。

其中,

  • public(公共访问修饰符)
    • 访问权限:最高级别的访问权限。
    • 作用:允许类的任何对象以及任何其他代码访问该类的成员(无论是数据成员还是成员函数)。
    • 使用场景:通常用于提供类的外部接口,即允许外部代码调用的成员函数或访问的数据成员。
  • protected(受保护的访问修饰符)
    • 访问权限:次高级别的访问权限。
    • 作用:允许类的对象、派生类(子类)以及类的内部代码访问该类的成员。
    • 使用场景:通常用于实现继承时,在基类中定义一些需要被子类访问但不需要被外界访问的成员。
  • private(私有的访问修饰符)
    • 访问权限:最低级别的访问权限。
    • 作用:只允许类的内部代码访问该类的成员。
    • 使用场景:通常用于隐藏类的内部实现细节,确保数据的封装性。
  • default(默认访问修饰符)
    • 访问权限:包(package)级别的访问权限。
    • 作用:允许同一包(package)中的其他类访问该类的成员,但不允许包外的类访问。

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

访问修饰符

访问权限

类内部

派生类内部

类的对象

同包其他类

说明

public

公有

可访问

可访问

可访问

可访问

允许外部访问

protected

受保护

可访问

可访问

不可访问

不可访问

允许派生类访问

private

私有

可访问

不可访问

不可访问

不可访问

仅允许类内部访问

default (包私有)

默认

可访问

不可访问

不可访问

可访问

同一包内可访问,默认访问级别

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



---E N D---

喜欢的记得关注哦!

您的支持是我们前进的动力!

职创未来|专注IT与新能源领域中高端人才培养

原文链接:,转发请注明来源!