c++复习--类和对象

news2024/11/26 10:37:56


目录

 

一、 类和对象(熟练掌握) 

 1. 面向对象和面向过程的理解

2. 面向对象三大特性是什么?

2.1. 封装

2.2 继承

2.3 多态

3. 8个默认成员函数

​3.1 构造和析构

3.1.1构造函数

      3.2 拷贝构造和拷贝赋值

3.2.1 拷贝构造

3.2.2 拷贝赋值

       3.3 移动构造和移动赋值

3.3.1 移动构造

3.3.2 移动复制

       3.4 operator& 不关注

       3.5什么情况下会默认生成?默认生成的都干了什么?

3.5.1什么情况下会默认生成

3.5.2默认生成的都干了什么?

       3.6 构造函数初始化列表

3.6.1 初始化列表价值

3.6.2 哪些成员必须在初始化列表初始化        

4. 对象实例化

4.1 对象大小计算--(注意)内存对齐

4.2 空类的大小?为什么是1

5. this

5.1 什么是this指针

5.2 this存在哪?

​编辑哪些运算符不能重载

.运算符重载意义是什么

7. static成员

8. 友元

8.1 友元函数

8.2 友元类


一、 类和对象(熟练掌握)
   1. 面向对象和面向过程的理解

面向对象:关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。典型语言又c++,java

面向过程:关注的是过程,分析出求解问题的步骤,典型语言是C语言,C语言通过函数调用逐步解决问题。

2. 面向对象三大特性是什么?

2.1. 封装

封装是将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。 封装本质上是一种管理,让用户更方便使用类。

比如:对于电脑这样一个复杂的设备,提供给用户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。

2.2 继承

2.3 多态

3. 8个默认成员函数

3.1 构造和析构

3.1.1构造函数



 

3.1.2析构函数 

 更对详细参考(70条消息) 类和对象—6个默认成员函数_对象的默认成员_秋秋是个小菜鸡的博客-CSDN博客

      3.2 拷贝构造和拷贝赋值

3.2.1 拷贝构造

3.2.2 拷贝赋值

 

拷贝赋值与拷贝构造的区别:

拷贝构造函数是一个对象初始化一块内存区域,这块内存就是新对象的内存区,而赋值构造函数时对于一个已经被初始化的对象来进行赋值操作。

拷贝赋值,拷贝构造,构造函数三者使用场景

对象不存在,且没用别的对象来初始化,就是调用了构造函数;

对象不存在,且用别的对象来初始化,就是拷贝构造函数

对象存在,用别的对象来给它赋值,就是赋值函数


       3.3 移动构造和移动赋值

3.3.1 移动构造

 

3.3.2 移动复制

移动赋值和移动构造类似,区别类似于拷贝构造和拷贝赋值


       3.4 operator& 不关注

取地址及const取地址操作符重载
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!


       3.5什么情况下会默认生成?默认生成的都干了什么?

3.5.1什么情况下会默认生成

我们定义一个空类。编译器会为我们默认生成一些函数。如果我们没有声明,编译器会帮我生成一个拷贝构造函数、一个拷贝赋值操作符和一个析构函数。同时如果我们声明构造函数的话,也会生成一个默认的构造函数

3.5.2默认生成的都干了什么?

1、默认构造函数不带任何参数,在对象初始化的时候调用。例如 Empty e1;
2、默认copy construct(拷贝构造)函数,用一个对象初始化另一个新对象的时候调用。例如Empty e2 = e1;
3、默认copy assignment(赋值)操作符,赋值的时候调用. 例如 Empty e2 ; e2 = e1;
4、默认析构函数,对象析构的时候调用.

说明:默认拷贝构造函数和默认赋值函数的实现基本上是一样的。会一一拷贝对象中的non-static成员数据。如果成员数据是基本类型,则直接进行赋值操作 e1.a=e2.b;

如果成员数据是自定义类型,则调用数据成员对应的默认拷贝构造函数,e1.a(e1.b);

如果数据对象是数组,则对每个元素进行拷贝操作 e1.arrayi;

copy construct 和 copy assignment 的区别在于调用场景不同。

如果是生成一个新对象则用 copy construct,

        例如 Empty e1 = e2(e1是个新对象);

如果是赋值一个已有的对象则用copy assignment,

        例如 Empty e1, e1 = e2(e1 是个已有的对象);


       3.6 构造函数初始化列表

 初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括 号中的初始值或表达式。 注意:每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

 

class Date
{
public:
 Date(int year, int month, int day)
 : _year(year)
 , _month(month)
 , _day(day)
 {}
 
private:
 int _year;
 int _month;
 int _day;
};


3.6.1 初始化列表价值

1.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化

2.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关


3.6.2 哪些成员必须在初始化列表初始化        

  1.  引用成员变量
  2. const成员变量
  3. 自定义类型成员(且该类没有默认构造函数时)

4. 对象实例化

用类类型创建对象的过程,称为类的实例化

1. 类是对对象进行描述的 ,是一个 模型 一样的东西,限定了类有哪些成员,定义出一个类 并没有分配实际 的内存空间 来存储它
2. 一个类可以实例化出多个对象, 实例化出的对象 占用实际的物理空间,存储类成员变量


4.1 对象大小计算--(注意)内存对齐

通过下面这段 代码及结构我们来分析一下
#include<iostream>
using namespace std;
// 类中既有成员变量,又有成员函数
class A1 {
public:
	void f1() {}
private:
	int _a;
};
// 类中仅有成员函数
class A2 {
public:
	void f2() {}
};
// 类中什么都没有---空类
class A3
{};
int main()
{
	cout << sizeof(A1)<<endl;
	cout << sizeof(A2) << endl;
	cout << sizeof(A3) << endl;

	return 0;

}

结论:一个类的大小,实际就是该类中成员变量之和,当然要注意内存对齐

 

4.2 空类的大小?为什么是1

空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。
(或者我们这样来思考:如果一个空类没有空间,那我们之前提到的默认生成的函数怎么办)
ps:结构体内存对齐规则
1. 第一个成员在与结构体偏移量为 0 的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS 中默认的对齐数为 8
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是
所有最大对齐数(含嵌套结构体的对齐数)的整数倍。


5. this


5.1 什么是this指针

C++ 编译器给每个 非静态的成员函数 增加了一个隐藏的指针参 数,让该指针指向当前对象 ( 函数运行时调用该函数的对象 ) ,在函数体中所有 成员变量 的操作,都是通过该 指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成
this指针的特性
1. this 指针的类型:类类型 * const ,即成员函数中,不能给 this 指针赋值。
2. 只能在 成员函数 的内部使用
3. this 指针本质上是 成员函数 的形参 ,当对象调用成员函数时,将对象地址作为实参传递给 this 形参。所以对象中不存储 this 指针
4. this 指针是 成员函数 第一个隐含的指针形参,一般情况由编译器通过 ecx 寄存器自动传递,不需要用 户传递


5.2 this存在哪?

 this指针本质上是成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针
6. 运算符重载


哪些运算符不能重载

这5个不能重载

.*

::

sizeof

?:

.
运算符重载意义是什么

 C++为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

函数名字为:关键字 operator 后面接需要重载的运算符符号
函数原型: 返回值类型  operator 操作符 ( 参数列表 )


7. static成员

声明为 static 的类成员 称为 类的静态成员 ,用 static 修饰的 成员变量 ,称之为 静态成员变量 ;用 static 修饰 成员函数 ,称之为 静态成员函数 静态成员变量一定要在类外进行初始化
特性
1. 静态成员 所有类对象所共享 ,不属于某个具体的对象,存放在静态区
2. 静态成员变量 必须在 类外定义 ,定义时不添加 static 关键字,类中只是声明
3. 类静态成员即可用 类名 :: 静态成员 或者 对象 . 静态成员 来访问
4. 静态成员函数 没有 隐藏的 this 指针 ,不能访问任何非静态成员
5. 静态成员也是类的成员,受 public protected private 访问限定符的限制


8. 友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。
友元分为: 友元函数 友元类

8.1 友元函数

问题:现在尝试去重载 operator<< ,然后发现没办法将 operator<< 重载成成员函数。 因为 cout 的输出流对 象和隐含的 this 指针在抢占第一个参数的位置 this 指针默认是第一个参数也就是左操作数了。但是实际使用中cout 需要是第一个形参对象,才能正常使用。所以要将 operator<< 重载成全局函数。但又会导致类外没办 法访问成员,此时就需要友元来解决。operator>> 同理。
友元函数 可以 直接访问 类的 私有 成员,它是 定义在类外部 普通函数 ,不属于任何类,但需要在类的内部声
明,声明时需要加 friend 关键字。
class Date
{
 friend ostream& operator<<(ostream& _cout, const Date& d);
 friend istream& operator>>(istream& _cin, Date& d);
public:
 Date(int year = 1900, int month = 1, int day = 1)
 : _year(year)
 , _month(month)
 , _day(day)
 {}
private:
 int _year;
 int _month;
 int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
 _cout << d._year << "-" << d._month << "-" << d._day;
 return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
 _cin >> d._year;
 _cin >> d._month;
 _cin >> d._day;
 return _cin;
}
int main()
{
 Date d;
 cin >> d;
 cout << d << endl;
 return 0;
}
说明 :
友元函数 可访问类的私有和保护成员,但 不是类的成员函数
友元函数 不能用 const 修饰
友元函数 可以在类定义的任何地方声明, 不受类访问限定符限制
一个函数可以是多个类的友元函数
友元函数的调用与普通函数的调用原理相同

8.2 友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
友元关系是单向的,不具有交换性。
如果 B A 的友元, C B 的友元,则不能说明 C A 的友元。
友元关系不能继承.
class Time
{
 friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成
员变量
public:
 Time(int hour = 0, int minute = 0, int second = 0)
 : _hour(hour)
, _minute(minute)
 , _second(second)
 {}
 
private:
 int _hour;
 int _minute;
 int _second;
};
class Date
{
public:
 Date(int year = 1900, int month = 1, int day = 1)
 : _year(year)
 , _month(month)
 , _day(day)
 {}
 
 void SetTimeOfDate(int hour, int minute, int second)
 {
 // 直接访问时间类私有的成员变量
 _t._hour = hour;
 _t._minute = minute;
 _t._second = second;
 }
 
private:
 int _year;
 int _month;
int _day;
 Time _t;
};

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

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

相关文章

[HDLBits] Exams/m2014 q4b

Implement the following circuit: module top_module (input clk,input d, input ar, // asynchronous resetoutput q);always(posedge clk or posedge ar) beginif(ar)q<1b0;elseq<d;end endmodule

【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态SQL

【JavaEE】MyBatis框架要点总结&#xff08;3&#xff09; 文章目录 【JavaEE】MyBatis框架要点总结&#xff08;3&#xff09;1. 多表查询1.1 映射表resultMap1.2 只有部分属性跨表查询1.2.1 依照常规去写代码1.2.2 用标签去实现接口 1.3 分多步的解决方案1.4 与多线程的结合 …

案例研究|大福中国通过JumpServer满足等保合规和资产管理双重需求

“大福中国为了满足安全合规要求引入堡垒机产品&#xff0c;在对比了传统型堡垒机后&#xff0c;发现JumpServer使用部署更加灵活&#xff0c;功能特性丰富&#xff0c;能够较好地满足公司在等保合规和资产管理方面的双重需求。” ——大福&#xff08;中国&#xff09;有限公…

【C/C++】STL queue 非线程安全接口,危险!

STL 中的 queue 是非线程安全的&#xff0c;一个组合操作&#xff1a;front(); pop() 先读取队首元素然后删除队首元素&#xff0c;若是有多个线程执行这个组合操作的话&#xff0c;可能会发生执行序列交替执行&#xff0c;导致一些意想不到的行为。因此需要重新设计线程安全的…

研发工程师玩转Kubernetes——启动、存活和就绪探针

启动&#xff08;Startup Probe&#xff09;、存活&#xff08;Liveness Probe&#xff09;和就绪探针(Readiness Probe)有其不同的用途和优先级。 优先级和用途 启动探针&#xff08;Startup Probe&#xff09;用于Pod内程序告诉kubernetes&#xff0c;其准备工作已经做好。…

iOS-砸壳篇(两种砸壳方式)

CrackerXI砸壳呢&#xff0c;当时你要是使用 frida-ios-dump 也是可以的&#xff1b; https://github.com/AloneMonkey/frida-ios-dump frida-ios-dump: 代码中需要更改的&#xff1a;手机中的内网ip 密码 等 最后放到我的砸壳路径里&#xff1a; python dump.py -l查看应用…

python_PyQt5运行股票研究python方法工具V1.2_增加折线图控件

承接【python_PyQt5运行股票研究python方法工具V1.1_增加表格展示控件】 地址&#xff1a;python_PyQt5运行股票研究python方法工具V1.1_增加表格展示控件_程序猿与金融与科技的博客-CSDN博客 目录 结果展示&#xff1a; 代码&#xff1a; 示例py文件代码&#xff08;低位股…

【go语言学习笔记】05 Go 语言实战

文章目录 一、 RESTful API 服务1. RESTful API 定义1.1 HTTP Method1.2 RESTful API 规范 2. RESTful API 风格示例3. RESTful JSON API4. Gin 框架4.1 导入 Gin 框架4.2 使用 Gin 框架4.2.1 获取特定的用户&#xff08;GET&#xff09;4.2.2 新增一个用户&#xff08;POST&am…

一位年薪50W的测试被开除,回怼的一番话,令人沉思

一位年薪35W测试工程师被开除回怼道&#xff1a;“反正我有技术&#xff0c;在哪不一样” 一技傍身&#xff0c;万事不愁&#xff0c;当我们掌握了一技之长后&#xff0c;在职场上说话就硬气了许多&#xff0c;不用担心被炒&#xff0c;反过来还可以炒了老板&#xff0c;这一点…

前后端分离------后端创建笔记(05)用户列表查询接口(上)

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

推荐5款能帮你解决各种问题的神器

​ 今天我要向大家推荐5款超级好用的效率软件&#xff0c;无论是在学习还是办公中都能够极大地提高效率。这些软件可以帮助你解决许多问题&#xff0c;而且每个都是真正的神器。 网速和硬件监控——TrafficMonitor ​ TrafficMonitor 是一款可以在任务栏或桌面悬浮窗显示系统…

配置service管理nginx

一.以源码形式安装的nginx&#xff0c;没有nginx.service 二.切换到service配置目录 三.编辑nginx.service文件 四.启动测试 1.我的开始报了这个问题&#xff0c;说没有这个/var/cache/nginx/client_temp目录&#xff0c;直接创建一个就好了 2.开启/关闭 一.以源码形式安装…

参加NPCon2023 AI模型技术与应用峰会(北京站):作为北京社区主理人的参会感受

参加NPCon2023 AI模型技术与应用峰会&#xff1a;作为北京社区主理人的参会感受 &#x1f3c9;&#x1f3c9;前言&#x1f3c9;&#x1f3c9;活动周边琳琅满目&#x1f3c9;&#x1f3c9;主题演讲&#x1f3c9;&#x1f3c9;亮点&#x1f3c9;&#x1f3c9;总结与展望 博主 默语…

项目管理的艺术:掌握成本效益分析

引言 在项目管理中&#xff0c;我们经常面临着如何有效地使用有限的资源来实现项目目标的挑战。为了解决这个问题&#xff0c;我们需要使用一种强大的工具——成本效益分析。通过成本效益分析&#xff0c;我们可以评估和比较不同的项目选项&#xff0c;选择最具成本效益的项目…

备战2024秋招面试题-最左匹配原则、索引失效情况、算法(最长回文子串)

前言&#xff1a; \textcolor{Green}{前言&#xff1a;} 前言&#xff1a; &#x1f49e;快秋招了&#xff0c;那么这个专栏就专门来记录一下&#xff0c;同时呢整理一下常见面试题 &#x1f49e;部分题目来自自己的面试题&#xff0c;部分题目来自网络整理 给我冲 学习目标&am…

Python爬虫——scrapy_基本使用

安装scrapy pip install scrapy创建scrapy项目&#xff0c;需要在终端里创建 注意&#xff1a;项目的名字开头不能是数字&#xff0c;也不能包含中文 scrapy startproject 项目名称 示例&#xff1a; scrapy startproject scra_baidu_36创建好后的文件 3. 创建爬虫文件&…

【构造】CF1761 E

Problem - 1761E - Codeforces 题意&#xff1a; 思路&#xff1a; Code&#xff1a; #include <bits/stdc.h>using i64 long long;void solve() {int n;std::cin >> n;std::vector g(n, std::vector<int>(n));std::vector<int> deg(n);for (int i …

电脑xinput1_3.dll丢失的解决方法?哪个解决方法更简单

最近在打开软件或者游戏的时候&#xff0c;电脑提示xinput1_3.dll文件丢失的错误。这个问题导致我无法运行某些游戏和应用程序。通过一番尝试和研究&#xff0c;我找到了一些修复xinput1_3.dll文件丢失的方法&#xff0c;并在此分享给大家。 首先&#xff0c;我了解到xinput1_3…

让音频翻译软件成为你的翻译利器吧

音频翻译功能是现代技术的一大进步&#xff0c;它通过语音识别技术和机器翻译技术&#xff0c;可以将音频文件自动翻译成其他语言的文字&#xff0c;让人们跨越语言障碍进行交流。现在市面上有很多种音频文件翻译软件&#xff0c;每个软件都有其独特的功能和特点。那么&#xf…

【状态模式】拯救if-else堆出来的屎山代码

前言 我想大家平时都在开发重都遇见过屎山代码&#xff0c;这些屎山代码一般都是由于复杂且庞大的if-else造成的&#xff0c;状态模式&#xff0c;是一种很好的优化屎山代码的设计模式&#xff0c;本文将采用两个业务场景的示例来讲解如何使用状态模式拯救屎山代码。 目录 前…