一文讲懂 C++ 类和对象(1)

0. 面向过程程序设计和面向对象程序设计的区别

面向对象程序设计往往关注的是怎么去做,是将解决问题的步骤分析出来,然后用函数把步骤一步一步实现,然后再依次调用就可以了。而面向对象是将构成问题的事物,分解成若干个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在解决问题过程中的行为。

因此我们之前讲到过的C语言是面向过程的,关注的是过程,分析出求解问题的步骤。而C++是面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
面向对象的特点:封装、继承、多态。
        封装性:就是把属性和方法都放在一个类里面,而且还可以通过访问类的权限属性给区分  开,更加安全,不想要释放的功能,直接搞成私有机制。
        继承性:就是把之前已经实现好的代码或者方法通过继承的方法拿过来使用,能节省大量的代码量,符合代码设计里面的继承优秀代码特性。
        多态性:由于可以继承多个类,能够组合成多种特性,但多态的关键是覆盖,就是同一个方法可以用不同的方式去实现,展现出多态性。
以上的特点我们会在后续详细解释到。

1. C++类的引入

了解c++,首先要了解类和对象,c++ 中的类可以看成c语言中的结构体的升级版,C 语言结构体是一种构造类型,可以包含若干个成员变量,成员变量的类型可以不同。在C++中,结构体内不仅可以定义变量,也可以定义函数。
C++中class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分 号不能省略。 类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者 成员函数。下面请看代码:
#include<iostream>
using namespace std;struct student
{int age;
};class student1 
{
public:void print()//成员函数,方法{cout <<"年龄:" << age << endl;}int age; //成员变量,属性private:int tele;
};int main()
{student s1;s1.age = 18;student1 s2;//创建对象s2.age = 20;s2.print();return 0;
}
 关于class(类)的几点说明:
(1)类的定义的最后有一个分号,它是类的一部分,表示类定义结束,不能省略。
(2)一个类可以创建多个对象,每个对象都是一个变量
(3)类是一种构造类型,大小的计算方法和 struct 一样,需要字节对齐
(4)类成员变量的访问方法:通过 . 或者 -> 来访问
(5)成员函数是类的一个成员,出现在类中,作用范围由类来决定,而普通函数是独立的,作用范围是全局或者某个命名空间。
代码中的 public 和 private 为类的访问控制,除此之外还有一个 protected,三个的说明如下:
(1) public 修饰的成员在类外可以直接被访问
(2)protected 和 private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
(3)访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
(4)如果后面没有访问限定符,作用域就到 } 即类结束。
(5)class的默认访问权限为private,struct为public(因为struct要兼容C)
(6)访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。
 C++中struct 和 class 的区别:
C++ 需要兼容 C 语言,所以 C++ 中 struct 可以当成结构体使用。另外 C++ 中 struct 还可以用来 定义类。和 class 定义类是一样的,区别是 struct 定义的类默认访问权限是 public,class定义的类默认访问权限是 private。
类的另一种定义方式:声明放在头文件当中,成员函数定义放在.cpp文件中,成员函数名前需要加类名 :: 。
// .h
struct student
{int age;
};class student1 
{
public:void print();int age;private:int tele;
};
// .cpp
void student1::print()
{cout <<"年龄:" << age << endl;
}

3. this指针

先看代码:
class Date
{ 
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout <<_year<< "-" <<_month << "-"<< _day <<endl;}private:int _year;     // 年int _month;    // 月int _day;      // 日
};int main()
{Date d1, d2;d1.Init(2023,3,12);d2.Init(2023,3,13);d1.Print();d2.Print();return 0;
}
有这样的一个问题: Date 类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函 数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?
C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏 的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量” 的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编 译器自动完成。
void print()
{cout << _data << endl;
}//编译处理包含this指针
void print(Data* this)
{cout << this->_data  << endl;
}
this指针的特性
(1) this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。
(2)只能在“成员函数”的内部使用
(3)this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给 this形参。所以对象中不存储this指针
(4)this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传 递,不需要用户传递。

4.构造函数和析构函数

在c++中,由一种特殊的成员函数,名字和类名相同,没有返回值,不需要用户显示调用(用户也不能调用),而是在创建对象的时候自动调用。 这种函数我们称为构造函数;和普通函数一样,构造函数是允许重载的,一个类可以有多个重载的构造函数,在创建对象时根据传递实参来判断调用哪一个构造函数。
(1)函数名必须和类型相同
(2)不能有返回值,函数体不能有return语句
(3)构造函数在定义对象时会自动调用,不需要手动调用
创建对象时系统会调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数进行清理工作,如释放分配的内存、关闭打开的文件等,这个函数就是析构函数。析构函数没有参数,不能被重载,一个类只能有一个析构函数,如果用户没有定义析构函数,编译器会提供默认的析构函数。
class Array
{private:int *m_data;   //数组的起始地址int m_size;public:Array();  //无参构造函数,函数名和类名一致,没有返回值Array(int s);  //有参构造函数Array(int s,int z);  //有两个参数的构造函数~Array();  //析构函数,函数名为:~类名 ,没有返回值,没有参数
};Array::Array()
{cout<<"Array的无参构造函数"<<endl;m_size = 5;m_data = (int *)malloc(sizeof(int) *m_size);
}Array::Array(int s)  //有参构造函数
{cout<<"Array的有一个参数的构造函数"<<endl;m_size = s;m_data = (int *)malloc(sizeof(int) * m_size);
}Array::Array(int s,int z)  //有两个参数的构造函数
{cout<<"Array的有两个参数的构造函数"<<endl;m_size = s;m_data = (int *)malloc(sizeof(int) * m_size);
}Array::~Array()
{cout<<"Array的析构函数"<<endl;if(m_data != NULL){free(m_data);m_data = NULL;}
}
Array a1; //创建对象,会自动调用构造函数

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/743168.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows达梦数据库(下载及使用)

解压安装包 点击最后一个文件 下一步 接受 下一步 下一步 下一步 点击初始化 开始

Oracle 10g字符编码

pl/sql developer查询数据时出现乱码&#xff0c;主要检查如下&#xff1a; 1、检查服务器编码 select * from v$nls_parameters;select * from nls_database_parameters;select userenv(language) from dual; 2、查看数据库可用字符集参数设置 select * from v$nls_valid_val…

Spring Cloud项目整合Sentinel及简单使用

说明&#xff1a;Sentinel是阿里巴巴开发的微服务治理中间件&#xff0c;可用于微服之间请求的流量管控、权限控制、熔断降级等场景。本文介绍如何在Spring Cloud项目中整合Sentinel&#xff0c;以及Sentinel的简单使用。 环境 首先搭建一个简单的微服务环境&#xff0c;有以…

编程向导-JavaScript-基础语法-块语句

梦里繁花落尽&#xff0c;此情未央&#xff0c;此意难忘&#xff0c;弦虽断&#xff0c;曲犹扬。&#xff01; 与技术共同呼吸&#xff0c;与程序员共命运。世树科技 承“技驱动&#xff0c;理致胜”理念、国风编程。 块语句 块语句&#xff08;Block&#xff09;用于组合零…

深度学习系列62:Agent入门

1 anget介绍和openai标准接口 agent的核心是其代理协同工作的能力。每个代理都有其特定的能力和角色&#xff0c;你需要定义代理之间的互动行为&#xff0c;即当一个代理从另一个代理收到消息时该如何回复。 agent目前大多使用openai标准接口调用LLM服务&#xff0c;说明如下。…

XmlHttpRequest responseType: ‘stream‘ 图片代理服务器

它是一个存在于原生 XMLHttpRequest 对象中的属性。在 Web API 中&#xff0c;XMLHttpRequest 对象用于发送 HTTP 或 HTTPS 请求到服务器&#xff0c;并接收响应。responseType 属性就是用来指定预期从服务器返回的响应数据的类型。 默认值 responseType的默认值为json&#x…

Netty线程模型详解

文章目录 概述单Reactor单线程模型单Reactor多线程模型主从Reactor多线程模型 概述 Netty的线程模型采用了Reactor模式&#xff0c;即一个或多个EventLoop轮询各自的任务队列&#xff0c;当发现有任务时&#xff0c;就处理它们。Netty支持单线程模型、多线程模型和混合线程模型…

linux内建命令/内部命令之caller

1.caller介绍 linux内建命令caller是用来打印函数的调用者信息&#xff0c;需将其放入到函数中才能生效。 2.样例 [rootelasticsearch ~]# cat caller.sh #!/bin/bashfunction1 () {caller 0 }function1 #line 8 [rootelasticsearch ~]# sh caller.sh 8 main caller.sh…

程序员的三重境界:码农,高级码农、程序员!

见字如面&#xff0c;我是军哥&#xff01; 掐指一算&#xff0c;我在 IT 行业摸爬滚打 19 年了&#xff0c;见过的程序员至少大好几千&#xff0c;然后真正能称上程序员不到 10% &#xff0c;绝大部分都是高级码农而已。 今天和你聊聊程序员的三个境界的差异&#xff0c;文章不…

DETR Doesn’t Need Multi-Scale or Locality Design

论文名称&#xff1a;PlainDetr 发表时间&#xff1a;ICCV2023 开源代码 作者及组织&#xff1a; Yutong Lin,Yuhui Yuan等&#xff0c;来自西安交大&#xff0c;微软亚洲研究院。 前言 自Detr以来&#xff0c;后续paper的改进的方向&#xff1a;主要是将归纳偏置重新又引入进…

react的高阶组件怎么用?

在 React 中&#xff0c;高阶组件&#xff08;Higher-Order Component&#xff0c;HOC&#xff09;是一种函数&#xff0c;接受一个组件作为参数&#xff0c;然后返回一个新的增强型组件。高阶组件本质上是一个函数&#xff0c;其目的是重用组件逻辑、增强组件功能以及在不改变…

pinia优化重复请求

目录 1 前言 2 使用步骤 2.1 安装pinia 2.2 定义一个store 2.3 在父组件即index.vue中调用方法 2.4 子组件使用获取到的值 1 前言 在我们的页面中常常存在多个组件&#xff0c;多个组件可能会对某个接口发送多次请求&#xff0c;为了避免这种情况&#xff0c;我们就需要使…

基于左逆的三点法测距,MATLAB函数

基于左逆的三点法MATLAB程序 不一定能用&#xff0c;可以借鉴&#xff0c;在锚点数量极少的时候&#xff0c;右拟无法使用&#xff0c;可以使用这个左逆&#xff08;当然&#xff0c;直接用pinv也行&#xff09; function [p_out] triposition(R_calcu,baseP) % p [5,5;10,…

分布式微服务 - 3.服务网关 - 4.Gateway

分布式微服务 - 3.服务网关 - 4.Gateway 项目示例&#xff1a; 项目示例 - 3.服务网关 - 3.Gateway 内容提要&#xff1a; 基本使用&#xff1a;配置方式、代码方式内置断言、自定义断言内置局部过滤器、自定义内置和全局过滤器 文档&#xff1a; 官网官网文档 基本使用…

重建3D结构方式 | 显式重建与隐式重建(Implicit Reconstruction)

在3D感知领域&#xff0c;包括3D目标检测在内&#xff0c;显式重建和隐式重建是两种不同的方法来表示和处理三维数据。它们各自有优势和局限&#xff0c;适用于不同的场景和需求。 显式重建&#xff08;Explicit Reconstruction&#xff09; 显式重建是指直接构建场景或物体的三…

云计算 3月12号 (PEX)

什么是PXE&#xff1f; PXE&#xff0c;全名Pre-boot Execution Environment&#xff0c;预启动执行环境&#xff1b; 通过网络接口启动计算机&#xff0c;不依赖本地存储设备&#xff08;如硬盘&#xff09;或本地已安装的操作系统&#xff1b; 由Intel和Systemsoft公司于199…

DEAP 自定义交叉操作

在遗传算法中&#xff0c;使用DEAP库来实现自定义的交叉操作可以非常灵活。如果你想模拟多个染色体的情况&#xff0c;通过在染色体的特定区间进行交叉&#xff0c;你需要自定义一个交叉函数。以下是一个示例&#xff0c;展示如何实现一个自定义的交叉函数&#xff0c;该函数允…

libigl 网格面片随机赋色

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 libigl的赋色方式非常简单,它统一由一个Eigen矩阵来进行管理,我们在进行赋色等操作时,只需要修改该矩阵即可(法向量等特征也是类似的操作)。 二、实现代码 //igl #include <igl/readOBJ.h> #include &l…

JVM简单调优

jdk自带了许多对jvm进行监控的程序&#xff0c;例如JVisualVM、jstack等等。 现在进行一些简单的对jvm的监控。 我们可以使用JVisualVM来对堆区进行图形化监控。 我们可以在命令行输入jvisualvm&#xff0c;然后就进入了jvisualvm的图形化界面。 然后我们随便执行一个主方法…

CDQ分治+树状数组,LOJ6270. 数据结构板子题

一、题目 1、题目描述 有 n 个区间&#xff0c;第 i 个区间是 [l_i,r_i]&#xff0c;它的长度是 r_i-l_i。 有 q 个询问&#xff0c;每个询问给定 L,R,K&#xff0c;询问被 [L,R] 包含的且长度不小于 K 的区间数量。 你想&#xff0c;像这种板子题&#xff0c;你随手写&#x…