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
默认为private
,struct
默认为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(子类可用)
├─ 类域规则
│ ├─ 作用域操作符`::`
│ └─ 编译查找顺序:当前域→类域
└─ 类的优势 ├─ 封装性 → 数据安全 ├─ 复用性 → 代码重用 └─ 模块化 → 结构清晰
重点提炼
-
类的本质:
- 自定义数据类型,捆绑数据与操作,实现封装的核心载体
-
访问控制黄金法则:
- 成员变量尽量
private
,对外接口用public
,继承相关用protected
- 成员变量尽量
-
类域核心作用:
- 解决命名冲突,明确成员归属,编译时通过
::
定位作用域
- 解决命名冲突,明确成员归属,编译时通过
-
与C语言的本质区别:
- 面向过程(C) vs 面向对象(C++),类是OOP的基础
常见问题与误区
Q1:类的成员函数必须在类内定义吗?
- A:不必。可在类内声明,类外通过
::
定义,提高代码可读性
Q2:struct
和class
有什么区别?
- A:唯一区别是默认访问权限:
struct
默认public
,class
默认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
非常感谢您的阅读,喜欢的话记得三连哦 |