IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++类和对象(上) -> 正文阅读

[C++知识库]C++类和对象(上)

📋 个人简介

  • 💖 作者简介:大家好,我是菀枯😜

  • 🎉 支持我:点赞👍+收藏??+留言📝

  • 💬格言:不要在低谷沉沦自己,不要在高峰上放弃努力!??

    v2-af3cfbda99d44f8eb114cc6c74c92253_720w

    前言

我们今天学习C++中比较重要的一部分:类和对象,因为有了类和对象的概念,我们才可以从C语言的面向过程编程C++中的面向对象编程

面向过程和面向对象

对于一个待解决的问题,我们可以从不同的角度去解决它。

比如点外卖这件事,它包含用户点餐,商家出餐,骑士送餐,用户取餐等过程。我们可以从头到尾,为每一个过程编写一段程序来解决问题。

我们也可以换一种角度来看待点外卖这个问题。它由三个对象组成:商家, 骑手,用户。三个对象每个人都有自己的方法:商家要接单,出餐。骑手要取餐,送餐。用户要点餐,取餐。那么点外卖这件事情就可以变成这三个对象的交互。

C语言是一种面向过程的语言,它解决问题就像我们处理点外卖问题的第一种办法,自上而下一步一步的去解决。而C++就是第二种办法,将问题抽象成对象之间的交互。

类的概念

类是对现实生活中一类具有共同特征的事物的抽象。我们都知道狗有各种各样的种类,比如牧羊犬,柯基,哈士奇等等。我们可以将他们进行抽象成一个类叫做Dog类。它有名字,年龄,性别。

类的定义

那么在C++中该如何创建这个类呢???

1647935710514

这个时候我们就可以用到C++中新引入的关键字class

class Dog{
  	char _name[20];
    int _age;
    char _sex[10];
};

注意:_并无特殊含义,只是在类中我们通常会对类中的变量作出标记而已

现在我们成功定义了一个Dog类,但是一只狗拥有的可不止有名字,年龄,性别这么简单。它还有吃饭,睡觉等等方法。

为了表示这些方法,C++中允许我们在类中书写函数,比如向下面这样

class Dog{
    void Init(){
        cin >> _name >> _age >> _sex;
    }
    
  	void eat(){
      	cout << _name << "正在吃饭" << endl;
  	}
    
    void sleep(){
        cout << _name << "正在睡觉" << endl;
    }
    
  	char _name[20];
    int _age;
    char _sex[10];
};

这样我们的Dog类就更加完善了,但是还有一些问题,目前的方法代码量都比较少。当方法比较多的时候,我们可能需要分文件进行书写,那该怎么操作呢???

我们可以在头文件中声明,在源文件中用我们之前学习到的::(域作用限定符)来为让我们的方法与类进行绑定。

假如下面有两个文件一个是Dog.h, 一个是Dog.cpp

//Dog.h
#include <iostream>

using namespace std;

class{
    void Init()
    void eat();
    void sleep();
    
    char _name[20];
    int _age;
    char _sex[10];
}
//Dog.cpp
#include "Dog.h"

void Dog::Init(){
    cin << _name << _age << _sex;
}

void Dog::eat(){
    cout << _name << "正在吃饭" << endl;
}

void Dog::sleep(){
    cout << _name << "正在睡觉" << endl;
}

类的访问限定符及封装

现在我们已经创建了一个小狗类,它既有属性:名字、年龄、性别,也有了方法:初始化、吃饭、睡觉。那么我们来试试这个Dog类可不可以被创建运行。

#include <iostream>

using namespace std;

class Dog{
    void Init(){
        cin >> _name >> _age >> _sex;
    }
    
  	void eat(){
      	cout << _name << "正在吃饭" << endl;
  	}
    
    void sleep(){
        cout << _name << "正在睡觉" << endl;
    }
    
  	char _name[20];
    int _age;
    char _sex[10];
};

int main(){
    Dog a;
    a.Init();              //类中元素的访问类似于我们C语言中的结构体,使用"."去访问
    return 0;
}

运行结果:image-20220513090357702

报错出现在a.Inti() 这一行,既然程序可以运行到a.Inti() 就说明我们的Dog类的创建没有问题,问题出现在访问类的方法上。那么为什么会有问题呢???

要解决这个问题,我们首先需要了解一下C++中的访问限定符

访问限定符

在C++中有3种访问限定符,protected(保护),private(私有),public(公有)。

image-20220513091656563

  1. public修饰的成员在类外可以直接访问。
  2. protected和private修饰的成员在类外不能被直接访问。
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现为止。
  4. class默认权限为private,struct的默认权限为public。

正是因为class的默认权限为private,所以才导致了我们刚刚无法直接调用Dog类中的Inti方法。为了外界可以调用这个函数,我们应该将它暴露在外界。

class Dog{
public:
    void Init(){
        cin >> _name >> _age >> _sex;
    }
    
  	void eat(){
      	cout << _name << "正在吃饭" << endl;
  	}
    
    void sleep(){
        cout << _name << "正在睡觉" << endl;
    }
    
private:
  	char _name[20];
    int _age;
    char _sex[10];
};

这样我们就可以正常的访问Dog类中的Inti方法了。

封装

C++为什么要引入这三个访问限定符呢?

这就不得不提到面向对象的三大特点之一:封装

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

实际上封装可以理解成一种管理方式:比如我们疫情的出入管理。如果我们什么都不管,任由小区内外的人随意出入,那么就有可能导致疫情越来越严重。封装就是将整个小区封起来,里面的成员只能从规定的出入口出入。这样就能有效的管理小区,控制住小区中的疫情。

在类中,我们将数据和方法都封装到一起,不想其他人直接进行操作的,我们用private/protected把成员进行封装,开放一些共有的成员函数对成员合理的访问。

类的实例化及其大小计算

类的实例化

类只是一个模板,它只规定了类中有哪些成员,就像我们在C语言中学习到的结构体一样,类本身不占据内存大小,只有当我们创建对象之后,对象占据内存的大小。

还是以我们的Dog类来举例子吧。

image-20220516070355041

这个我们可以把他类比成函数的声明,它只是告诉编译器类中有哪些东西,并不会开辟内存给这个类。只有当我们在函数中定义了对象,才会开辟空间。

int main(){
    Dog a;                //此时为a这个对象开辟空间
    return 0}

类的大小

那么对于一个类,它里面既有成员函数又有成员变量,类的大小该怎么计算呢???

我们假设一下,应该只有两种情况:

  • 对象中包含类的所有成员

    image-20220516071900982

  • 对象中只有成员变量,无成员函数,成员函数放在其他区域。

image-20220516095804436

接下来我们来实验一下,哪一种才是正确的结果呢?

int main(){
    Dog a;
    cout << sizeof(a) << endl;
    return 0;
}

image-20220516100114426

(不知道36是怎么计算出来的同学,可以去看看这个: C语言自定义类型梳理)

结论:一个类的大小,实际就是该类中“成员变量”之和,同时还要对成员变量进行内存对齐

this指针

现在我们知道了,对象里面只有成员变量的大小,而无成员函数,那么程序是怎么知道是哪一个对象在使用这个方法呢?

如果我们现在有两个对象,一个Dog a,一个Dog b,a和b都去调用同一个方法,是什么效果呢?

image-20220516102507371

我们给Dog a取名为:小花,年龄:5,性别:女。

Dog b取名为:小黄,年龄:3,性别:男。

接下来我们看看输出结果是什么:image-20220516102747965

我们发现程序可以很好的识别出是哪一个对象在调用这个方法,那么这是怎么实现的呢?

这就不得不提到C++中的this指针了,其实我们在调用类中的方法时,有一个隐含的指针参数,这个指针指向的就是我们当前的对象。

我们写的程序是左边的样子,但实际的样子是右边。

image-20220516114953584

this指针指向调用这个方法的对象,所以不同对象才能准确访问不同的成员变量。

结语

1647941444633

欢迎各位参考与指导!!!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-19 11:50:18  更:2022-05-19 11:51:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/12 23:44:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码