C++从入门到实战(五)类和对象(第一部分)为什么有类,及怎么使用类,类域概念详解(附带图谱等更好对比理解)

news/2025/3/22 10:53:26/

C++从入门到实战(五)类和对象(第一部分)为什么有类,及怎么使用类,类域概念详解

  • 前言
  • 一、为什么要有类?类的好处
    • (一).与 C 语言对比类的作用
      • 1.1 数据和操作的组织方式
      • 1.2 代码复用性
      • 1.3. 安全性
    • (二).类的好处
  • 二、类的定义
    • (一)类定义格式
    • (二)访问限定符
      • 2.1封装、方法、属性和对象概念名词解释
      • 2.2 访问限定符public,private与protected
        • public(公共区域)
        • private(私人区域)
        • protected(受保护区域)
  • 三、类域
        • 3.1 类域的概念
  • 总结 核心概念速记 :
      • 知识对比表格
      • 知识图谱
      • 重点提炼
      • 常见问题与误区


前言

  • 在上一篇博客中,我们深入探讨了 C++ 中几个重要特性:C++ 引用、inline 关键字以及 nullptr

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482

上一篇博客地址与摘要

https://blog.csdn.net/2402_83322742/article/details/145622425?spm=1001.2014.3001.5501

C++ 引用让我们可以为变量取别名,提高了代码的简洁性和安全性;inline 关键字通过在编译时将函数调用处用函数体替换,减少了函数调用开销;nullptr 则避免了与 0 或 NULL 相关的二义性问题。通过掌握这些特性,我们能够编写出更具灵活性和高效性的代码。

这一篇,我们将继续探索 C++ 中另外几个重要的知识点:类和对象(上)。这些内容将进一步丰富我们对 C++ 语言的理解,为编写更加复杂和高效的程序提供有力支持


一、为什么要有类?类的好处

  • 想象你要管理一家宠物店,店里有很多宠物,每只宠物都有自己的信息(像名字、年龄、品种)和行为(吃东西、睡觉)。
  • 在编程里,如果没有类,这些信息和行为就会乱成一团,很难管理。而类就像是一个 “模板”,可以把宠物的信息和行为组织在一起。有了这个模板,你就能轻松地创建出很多只宠物,并且方便地对它们进行操作

在这里插入图片描述

  • 类的简单代码,后面会详细讲类的知识现在看一下就好
#include <iostream>// 定义 Rectangle 类
class Rectangle {
private:// 私有成员变量,分别表示矩形的长和宽double length;double width;public:// 构造函数,用于初始化矩形的长和宽Rectangle(double l, double w) {length = l;width = w;}// 成员函数,用于计算矩形的面积double getArea() {return length * width;}// 成员函数,用于计算矩形的周长double getPerimeter() {return 2 * (length + width);}
};int main() {// 创建一个 Rectangle 对象,长为 5,宽为 3Rectangle rect(5, 3);// 调用成员函数计算并输出矩形的面积和周长std::cout << "矩形的面积是: " << rect.getArea() << std::endl;std::cout << "矩形的周长是: " << rect.getPerimeter() << std::endl;return 0;
}

(一).与 C 语言对比类的作用

1.1 数据和操作的组织方式

C 语言数据和操作是分开的。比如你要处理宠物信息,数据(像宠物的名字、年龄)是单独存储的,操作(像打印宠物信息)也是单独的函数。这样一来,当数据和操作越来越多的时候,代码就会变得很混乱,很难管理。
C++ 类把数据和操作捆绑在一起。你只需要关注这个 “宠物类”,里面的数据和操作都已经组织好了,使用起来非常方便。

1.2 代码复用性

C 语言如果要复用代码,通常需要复制粘贴,然后再进行修改。这样不仅麻烦,还容易出错。
C++ 类通过继承和多态等特性可以轻松地复用代码。比如你已经有了一个 “宠物类”,现在要创建一个 “猫类”,只需要让 “猫类” 继承 “宠物类”,再添加一些猫特有的信息和行为就可以了。

1.3. 安全性

C 语言数据是公开的,任何地方的代码都可以直接访问和修改数据,容易导致数据被意外修改,引发错误。
C++ 类可以通过访问控制符(如private、protected)来限制外部代码对数据的访问,提高了数据的安全性。

(二).类的好处

1数据和操作捆绑

类能把数据(比如宠物的名字、年龄)和操作这些数据的函数(比如给宠物喂食、让宠物睡觉)放在一起。这样做就好像把宠物的所有相关信息和行为都装在一个 “袋子” 里,方便携带和管理。

2. 方便复用代码

当你创建了一个宠物类后,就可以用这个类创建出很多不同的宠物对象。每个宠物对象都继承了类里定义的信息和行为,不需要每次都重新编写相同的代码。就好比你有了一个制作宠物的 “模具”,可以用它做出很多不同的宠物。

3. 增强安全性

类可以控制外部代码对内部数据的访问。你可以决定哪些数据和函数是可以被外部访问的,哪些是只能在类内部使用的。这就像给你的宠物店加上了一些 “门锁”,保护了宠物的隐私和安全。

4. 让代码更有条理

类可以把不同功能的代码分开,每个类负责自己的事情。这样,当你要修改某个功能时,只需要修改对应的类,不会影响到其他部分的代码。就像宠物店被分成了不同的区域,每个区域负责不同的工作,管理起来更加轻松。

二、类的定义

(一)类定义格式

  • 在 C++ 中,class 是定义类的关键字。以下是一个简单的类定义示例:
#include <iostream>
#include <string>// 定义一个名为 Person 的类
class Person 
{
private:// 私有成员变量,存储人名std::string name;public:// 构造函数,用于初始化 name 成员变量Person(const std::string& n) : name(n) {} //构造函数,后面会详细讲// 公有成员函数,用于输出该人的介绍信息void introduce() {std::cout << "Hello, my name is " << name << "." << std::endl;}
};int main() 
{// 创建一个 Person 类的对象,名字为 "Alice"Person alice("Alice");// 调用 introduce 成员函数,输出介绍信息alice.introduce();return 0;
}

下面对这段 C++ 代码的详细讲解

class Person 
{
private:std::string name;public:Person(const std::string& n) : name(n) {} void introduce() {std::cout << "Hello, my name is " << name << "." << std::endl;}
};

class Person:使用 class 关键字声明了一个名为 Person 的类。
类是一种用户自定义的数据类型,它可以封装数据(成员变量)和操作这些数据的函数(成员函数)。
私有成员变量

private:std::string name;

private 是访问修饰符,它表示在其下面声明的成员(变量或函数)只能在类的内部被访问,外部代码无法直接访问这些私有成员。

公有成员函数

void introduce() 
{std::cout << "Hello, my name is " << name << "." << std::endl;
}

introduce() 是一个公有成员函数,外部代码可以通过 Person 类的对象来调用这个函数。

(二)访问限定符

  • 在 C++ 里,类是实现封装的一种方式,它把对象的属性和方法整合在一起,让对象功能更完善,还能通过访问权限控制对外提供的接口。

2.1封装、方法、属性和对象概念名词解释

  • 封装是面向对象编程中的一个重要概念,它指的是将数据(属性)和操作数据的函数(方法)组合在一起,形成一个独立的单元(即类)。

封装的目的是隐藏内部实现细节,只通过类的接口(即公开的方法)与外部交互。

  • 如下面的代码
class BankAccount {
private:double balance; // 属性,隐藏在类内部public:void deposit(double amount); // 方法,提供接口void withdraw(double amount); // 方法,提供接口double getBalance() const; // 方法,提供接口
};
  • 方法
  • 方法是类中定义的函数,用于实现对类属性的操作或完成特定的功能。方法可以访问类的属性,并且可以根据需要对外提供接口。
  • 例如
void BankAccount::deposit(double amount) {if (amount > 0) {balance += amount;}
}
  • 属性
  • 属性是类中定义的变量,用于存储类的状态或数据。
private:double balance; // 属性,用于存储账户余额
  • 对象
  • 对象是类的实例,是类的具体表现形式。
  • 通过对象,可以访问类的属性和方法。
  • 例如
BankAccount myAccount; // 创建一个对象
myAccount.deposit(100.0); // 调用对象的方法
double currentBalance = myAccount.getBalance(); // 调用对象的方法

这些概念共同构成了面向对象编程的基础,使得代码更加模块化、可维护和可扩展。

2.2 访问限定符public,private与protected

  • 在 C++ 里,public、private 和 protected 这些访问限定符就像是房屋的不同区域,它们决定了谁能进入以及可以做什么
public(公共区域)
  • 这就好比房屋的公共区域,像客厅、走廊,任何人都能自由进出,想做什么都可以。在 C++ 类里,public 成员可以在类的外部直接被访问,也就是不管在什么地方,只要能接触到这个类的对象,就可以使用这些成员。
private(私人区域)
  • 这类似于房屋的卧室只有房屋主人才能进去。在 C++ 里,private 成员只能在类的内部被访问,类的外部没办法直接使用这些成员。这是一种保护机制,能防止外部随意修改或访问类的关键数据。
protected(受保护区域)
  • 这就像是房屋里孩子的房间,除了主人之外,孩子也能进去。在 C++ 中,protected 成员和 private 成员类似,在类外部不能直接访问,但在该类的子类中可以访问。也就是说,protected 成员可以在类的家族内部使用。
# include <iostream>
using namespace std;
class House
{
public:void showLivingRoom() {cout << "Welcome to the living room!" << endl;}private:void showBedroom() {cout << "This is the bedroom, you can't enter!" << endl;}
protected:// 受保护区域,类内部和子类能访问void showKidsRoom() {cout << "This is the kids' room." << endl;}
};int main() {House myHouse;myHouse.showLivingRoom(); // 可以访问,因为是 public 成员// myHouse.showBedroom(); // 错误,不能访问 private 成员// myHouse.showKidsRoom(); // 错误,不能访问 protected 成员return 0;
}

在这里插入图片描述

三、类域

在这里插入图片描述

3.1 类域的概念
  • 类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤::作⽤域操作符指明成员属于哪个类域。

我们简单讲下这段话

  • 类域可以理解成一个 “专属地盘”,每个类都有自己独立的类域
  • 就好像每个国家都有自己的领土范围一样。类里的所有成员(包括成员变量和成员函数)都处在这个类域当中。
  • 在类的内部,你可以直接使用类的成员,因为编译器知道你是在这个类的 “地盘” 里活动。但当你要在类的外部定义成员函数时,就得通过 :: 作用域操作符来明确指出这个成员函数属于哪个类的 “地盘”。
#include <iostream>// 定义一个名为 Stack 的类
class Stack {
public:// 声明一个成员函数 Initvoid Init();private:// 声明一个成员变量 arrayint array[100];
};// 在类体外定义成员函数 Init,使用 :: 指明属于 Stack 类域
void Stack::Init() {// 在成员函数里可以使用类的成员变量 arrayfor (int i = 0; i < 100; ++i) {array[i] = 0;}std::cout << "Stack initialized." << std::endl;
}int main() {Stack myStack;// 调用 Init 成员函数myStack.Init();return 0;
}

在这里插入图片描述

  • 在这个代码里,Stack 类有自己的类域。
  • Init 函数在类里只是声明,在类外定义时,使用 Stack::Init() 明确指出 Init 是 Stack 类的成员函数。
  • 在 Init 函数里使用 array 成员变量时,编译器就会到 Stack 类域里去查找 array 的定义。
  • 要是不指定 Stack::,编译器就会把 Init 当成全局函数,在全局作用域里找不到 array 的定义,就会报错。

总结 核心概念速记 :

核心概念速记

类与对象核心 = 封装三要素 + 访问控制 + 类域作用

  • 封装三要素
    • 属性(成员变量) → 方法(成员函数) → 访问控制(public/private/protected)
  • 类域规则
    • 成员默认访问权限:class默认为privatestruct默认为public
    • 类外定义成员需用::作用域操作符

知识对比表格

C语言 vs C++类的特性对比

维度C语言C++类
数据组织数据与函数分离数据(属性)与函数(方法)捆绑
代码复用复制粘贴修改继承/多态/模板
安全性数据全局可见访问控制符(private/protected)
扩展性函数参数扩展复杂类成员增减灵活

类的成员访问控制

访问限定符对比表

限定符类内访问类外访问子类访问典型用途
public✔️✔️✔️对外接口(如show()
private✔️私有数据(如balance
protected✔️✔️子类继承数据

类域与作用域操作符

类域作用示意图

全局作用域  
├─ 类作用域(Stack)  
│  ├─ public: Init()  
│  └─ private: array[100]  
└─ main()  └─ Stack myStack; → 访问类域成员

关键代码示例

class Stack {
public:void Init(); // 声明在类域
};// 类外定义需指定类域
void Stack::Init() { array[0] = 0; // 编译器到Stack类域查找array
}

知识图谱

类和对象(上)  
├─ 类的定义  
│  ├─ 语法结构:class关键字 + 成员列表  
│  ├─ 成员类型:属性(变量)+ 方法(函数)  
│  └─ 默认访问:class→private,struct→public  
├─ 访问控制  
│  ├─ public(公共接口)  
│  ├─ private(类内私有)  
│  └─ protected(子类可用)  
├─ 类域规则  
│  ├─ 作用域操作符`::`  
│  └─ 编译查找顺序:当前域→类域  
└─ 类的优势  ├─ 封装性 → 数据安全  ├─ 复用性 → 代码重用  └─ 模块化 → 结构清晰  

重点提炼

  1. 类的本质

    • 自定义数据类型,捆绑数据与操作,实现封装的核心载体
  2. 访问控制黄金法则

    • 成员变量尽量private对外接口用public继承相关用protected
  3. 类域核心作用

    • 解决命名冲突,明确成员归属,编译时通过::定位作用域
  4. 与C语言的本质区别

    • 面向过程(C) vs 面向对象(C++),类是OOP的基础

常见问题与误区

Q1:类的成员函数必须在类内定义吗?

  • A:不必。可在类内声明,类外通过::定义,提高代码可读性

Q2:structclass有什么区别?

  • A:唯一区别是默认访问权限struct默认publicclass默认private

Q3:为什么成员变量要设为private

  • A:防止外部直接修改,通过public方法控制读写逻辑(如校验数据合法性)

技术演进脉络

C语言结构体 → C++类 → 继承 → 多态 → 模板  ↓          ↓           ↓       ↓       ↓  
数据聚合 → 数据+操作 → 代码复用 → 动态绑定 → 泛型编程  

以上就是这篇博客的全部内容,下一篇我们将继续探索更多精彩内容。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482

非常感谢您的阅读,喜欢的话记得三连哦

在这里插入图片描述


http://www.ppmy.cn/news/1581120.html

相关文章

【leetcode hot 100 208】实现Trie(前缀树)

解法一&#xff1a;字典树 Trie&#xff0c;又称前缀树或字典树&#xff0c;是一棵有根树&#xff0c;其每个节点包含以下字段&#xff1a; 指向子节点的指针数组 children。对于本题而言&#xff0c;数组长度为 26&#xff0c;即小写英文字母的数量。此时 children[0] 对应小…

前端引擎革命:界面量子化渲染架构

引言&#xff1a;DOM坍塌后的次元跃迁 Chrome V8引擎实现98% ES2023规范支持&#xff0c;React 19并发渲染突破百万节点秒级更新。Shopify Hydrogen框架首屏用时降至380ms&#xff0c;Next.js 14服务端组件缓存命中率93%。Figma实时协同引擎支持500人同时操作&#xff0c;WebA…

个人作品集模板!除了Figma还可以选择什么软件?

在竞争激烈的设计行业中&#xff0c;作品集不仅是设计师能力的直观体现&#xff0c;更是打开职业机会的“金钥匙”。一份优秀的作品集需要兼具视觉吸引力、逻辑清晰度和专业深度。本文将从设计原则、工具选择到排版技巧&#xff0c;为你提供系统化的创作指南&#xff0c;并推荐…

材质 × 碰撞:Threejs 物理引擎的双重魔法

材质 在物理引擎中&#xff0c;材质(Material)用于描述物体的物理属性&#xff0c;例如摩擦力、弹性等。 const material new CANNON.Material("materialName");CANNON.Material&#xff1a; 物理材质&#xff0c;用于模拟物体之间的摩擦力、弹性等物理属性。 ma…

算法题(103):数独

审题&#xff1a; 本题需要我们找出数独的解&#xff0c;并打印出来 时间复杂度分析&#xff1a; 本题是9*9的数独格子&#xff0c;所以数据量小于25&#xff0c;可以使用2^n的算法 思路&#xff1a; 方法一&#xff1a;深度优先搜索 首先确定搜索及插入策略&#xff1a; 我们采…

[特殊字符] 2025蓝桥杯备赛Day10——B2120 单词的长度

&#x1f50d; 2025蓝桥杯备赛Day10——B2120 单词的长度 &#x1f680; 题目速览 题目难度&#xff1a;⭐️ 适合掌握字符串基本操作 考察重点&#xff1a;字符串分割、空格处理、标点符号处理 B2120 单词的长度 题目描述 输入一行单词序列&#xff0c;相邻单词之间由 …

鸿蒙开发工程师简历项目撰写全攻略

一、项目结构的黄金法则 建议采用「41」结构&#xff1a; 项目背景&#xff08;业务价值&#xff09;技术架构&#xff08;鸿蒙特性&#xff09;核心实现&#xff08;技术难点&#xff09;个人贡献&#xff08;量化成果&#xff09;附加价值&#xff08;延伸影响&#xff09; …

机器学习算法实战——天气数据分析(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​ 1. 引言 天气数据分析是气象学和数据科学交叉领域的一个重要研究方向。随着大数据技术的发展&#xff0c;气象数据的采集、存储和分…