C++程序进阶学习

目录

引言  

C++内存分区

一、内存分区模型

二、 程序运行前

 三、程序执行后

C++引用

引用的语法

作用

本质

优点

C++封装

C++对象特性

C++对象模型和this指针

C++友元

C++运算符重载

C++继承

C++多态

C++文件


引言  

        看过我博客的朋友可能都了解这篇文章内容了,这篇博客是由我单独每天撰写的C++内容合集,重新整理完善了内容;也算是自己重新学习,也和大家一起学习,如果对大家的学习有帮助,那自然更好,如果大家在学习的过程中发现文章内容有问题或者不懂的,希望大家能在评论区积极讨论,我看到了也会回复!!!

C++内存分区

一、内存分区模型

在执行C++程序时,我们可将内存划分为四个区域

  • 代码区:存放函数体的二进制代码,由操作系统进行管理(我们一般的代码都在里面)
  • 全局区:存放全局变量和静态变量以及常量
  • 栈区:存放函数的参数值,局部变量等,这个区域则由编译器自动分配释放
  • 堆区:这一区域则是程序员自己分配和释放,程序结束时也会由系统回收

为什么要区分这些区域呢? 

将数据放在不同区域,数据所占空间的时间不同,这也使我们能更灵活的使用数据。

二、 程序运行前

在程序编译后,未执行该程序前分为两个部分

1.代码区:

存放CPU执行的机器指令

我们需要注意代码区是只读不写的

2.全局区:

 三、程序执行后

在程序执行后可分为两部分

栈区:这里我们需要注意的是,在编写程序时,不能返回局部变量的地址

示例:

#include<iostream>
using namespace std;//栈区的数据由编译器管理开辟和释放int* func()//形参数据也放在栈区
{int c_a = 10;return &c_a;
}int main()
{int * p = func();cout << *p << endl;//第一次可以打印正确的数字,这个时候他的值以及被编译器释放了,只是因为编译器做了保留cout << *p << endl;//第二次这个数据就不再保留system("pause");return 0;
}

堆区:在C++中主要利用new在堆区开辟内存

示例:

#include<iostream>
using namespace std;int* func()
{int * p = new int(1);return p;
}int main()
{int*p = func();cout << *p << endl;cout << *p << endl; cout << *p << endl;//只要我们没有人为的去释放内存,是可以一直输出的system("pause");return 0;
}

C++引用

引用的语法

        数据类型  & 别名 = 原名

作用

        1、函数传参时,可以利用引用技术让形参修饰实参

        2、引用是可以作为函数的返回值存在的(同样不可以返回局部变量引用)

本质

        引用的本质在C++内部实现一个指针常量

优点

        可以简化指针修改实参

示例1:

#include<iostream>using namespace std;int main(){int a = 1;int &b = a;//创建引用cout << "a=" << a << endl;//输出均是1cout << "b=" << b << endl;b = 2;cout << "a=" << a << endl;//输出均是2cout << "b=" << b << endl;system("pause");return 0;}

注意:

        1.引用必须要初始化

        2.一旦初始化了,就不可以更改了!!!!

我们也同样可以来看一下引用其本质,下面一个示例就能很好的说明:

示例2:

#include<iostream>using namespace std;//发现是引用,转换为 int* const b = &a;void func(int &b){b = 100;//ref是引用,转换为*b = 100}int main(){int a = 10;//自动转换为 int* const b = &a,这就相当于一个指针常量,指针常量我们都知道是指针指向不可改,这也充分说明了我们之前为什么说引用不可更改int &b = a;ref = 20;//当编译器内部发现 ref 是引用,编译器自动将其转换为:*b=20;cout << "a = " << a << endl;cout << "b = " << b << endl;func(a);system("pause");return 0;}

        当我们在编写程序时就无需考虑其是怎样去转换的,讲解引用本质,只是为了帮助我们理解。我们只需掌握引用的语法结构、作用以及注意事项!!! 

C++封装

        C++认为万事万物都皆为对象,对象上有其属性和行为

    类在设计时,可以把属性和行为加以控制,可以设置三种权限:

  1. public      公共权限   成员  类内可以访问  类外可以访问
  2. protected   保护权限   成员  类内可以访问  类外不可以访问
  3. private     私有权限    成员  类内可以访问  类外不可以访问

        这里使用class去创建类,前面我们学习了struct创建体,二者并没有什么差别,struct和class唯一的区别就是默认的访问权限不同:struct默认权限为公共,class默认权限为私有

举一个简单的例子,求圆的周长:

        首先我们进行简单分析:我们知道圆的周长公式为2ΠR,Π是个定数,一般使用3.14,简单定义就行;R就是需要去设置的,这里我们就设计一个类,一个类里面包含属性和行为,圆的属性有圆心、半径或者直径,这里我们只需要设置一个半径就可以了,行为:就是我们要求的内容,设定为一个函数。下面就是代码:

#include<iostream>
using namespace std;const double PI = 3.14;//class 代表设计一个类,类后面紧跟着的就是类的名称
class Circle
{public:  //公共权限//属性//半径int m_r;//行为//获取圆的周长double calculateZC(){return 2 * PI * m_r;}
};int main()
{//实例化  创建一个对象Circle c;//给圆对象 的属性进行赋值c.m_r = 10;cout << "圆的周长:" << c.calculateZC() << endl;system("pause");return 0;
}

        上面代码我们使用了最简单的类的创建,就是将属性都统一放置在公共权限中,但在我们通常编写程序时将这些放在私有权限,将设置数据和调取数据函数放在公共权限,这样有以下两个优点:

优点1:将所有成员属性设置为私有,可以自己控制读写权限

优点2:对于写权限,我们可以检测数据的有效性

我们同样以求圆周为例:

#include<iostream>
using namespace std;//圆周率
const double PI = 3.14;//class 代表设计一个类,类后面紧跟着的就是类的名称
class Circle
{
public://公共权限//  设置半径void setR(int r){m_R = r;}// 读取半径int getR(){return m_R;}//行为//获取圆的周长double getZC(){return 2 * PI * m_R;}//私密权限
private://属性//半径int m_R;
};int main()
{//实例化 创建具体的圆(对象)Circle c;//给圆对象 的属性进行赋值c.setR(10);cout << "圆的周长:" << c.getZC() << endl;system("pause");return 0;
}

        这样我们就能很好的控制数据的权限,在编写程序时需要分辨这个数据,在主函数中是否需要修改,是否需要读取,只有这样才能尽可能的减少编写错误。

C++对象特性

        在C++中,类的构造函数和析构函数是处理对象初始化和清理的关键。下面是构造函数和析构函数的详细解释:

一、构造函数

构造函数用于对象的初始化。构造函数的特点和使用如下:

  • 函数名与类名相同:构造函数的名称必须和类的名称完全相同,这样编译器才能识别它是构造函数。
  • 没有返回值:构造函数没有返回值类型,因此不需要写void或其他返回类型。
  • 可以有参数,可以重载:构造函数可以有参数,可以根据不同参数进行重载,这使得可以用不同方式初始化对象。
  • 自动调用:在创建对象的时候,构造函数会自动调用,而且每个对象的构造函数只会调用一次。

二、析构函数

析构函数用于对象销毁前的清理操作。析构函数的特点和使用如下:

  • 函数名与类名相同,前加 ~:析构函数的名称与类名相同,但前面要加上波浪号 ~
  • 没有返回值:析构函数也没有返回值类型,因此不需要写void或其他返回类型。
  • 不能有参数,不能重载:析构函数不能有参数,也不能被重载。
  • 自动调用:对象在销毁前会自动调用析构函数,每个对象的析构函数也只会调用一次。

下列写了三类函数的语法,以及三种调用方式:

#include<iostream>
using namespace std;class Person
{
public://构造函数Person(){cout << "Person的无参构造函数调用" << endl;}Person(int a){age = a;cout << "Person的有参构造函数调用" << endl;}//拷贝构造函数Person(const Person &p){//将传入的人的身上的所有属性,拷贝到我身上cout << "Person的拷贝构造函数调用" << endl;age = p.age;}~Person(){cout << "Person的析构函数调用 " << endl;}int age;
};void test()
{//1、括号法Person p1;//默认构造函数调用Person p2(10);//有参构造函数Person p3(p2);//拷贝构造函数//2、显示法Person p1;Person p2 = Person(10);//有参构造Person p3 = Person(p2);//拷贝构造//3、隐式转换法Person p4 = 10;//相当于  写了 Person p4 = Person(10)Person p5 = p4;
}int main()
{test();system("pause");return 0;
}

        在C++中,构造函数的调用和生成有一些特定的规则。了解这些规则有助于正确管理类的构造和销毁。以下是详细的说明:

1. 编译器默认添加的函数

当你定义一个类时,C++编译器会自动为类添加至少三个默认函数:

  • 默认构造函数:如果你没有定义任何构造函数,编译器会提供一个无参的默认构造函数。
  • 析构函数:编译器会提供一个默认的析构函数,用于对象销毁时的清理工作。
  • 拷贝构造函数:编译器会提供一个默认的拷贝构造函数,该函数执行成员变量的浅拷贝(值拷贝)。

示例代码:

class MyClass {// 如果没有定义任何构造函数、析构函数或拷贝构造函数// 编译器会自动生成以下函数:
public:MyClass();              // 默认构造函数~MyClass();             // 默认析构函数MyClass(const MyClass& other); // 默认拷贝构造函数
};

 2. 有参构造函数的影响

  • 覆盖默认构造函数:如果你定义了一个有参构造函数,编译器就不再提供默认的无参构造函数。
  • 依然提供拷贝构造函数:即使定义了有参构造函数,编译器仍然会提供默认的拷贝构造函数(如果没有显式定义)。

示例代码:

class MyClass {
public:MyClass(int value);    // 有参构造函数// 编译器不会再提供默认构造函数// 编译器依然会提供默认的拷贝构造函数和析构函数
};

 3. 拷贝构造函数的影响

  • 覆盖默认拷贝构造函数:如果你定义了拷贝构造函数,编译器就不再提供默认的拷贝构造函数。
  • 不影响其他普通构造函数:即使定义了拷贝构造函数,编译器仍然会提供默认构造函数和析构函数(如果没有显式定义)。

示例代码:

class MyClass {
public:MyClass(const MyClass& other);  // 拷贝构造函数// 编译器不会再提供默认的拷贝构造函数// 编译器依然会提供默认构造函数和析构函数(如果没有显式定义)
};

 4. 手动定义所有特殊成员函数

        在实际开发中,通常会根据需要手动定义所有的特殊成员函数,以确保对象的正确构造和销毁。

示例代码:

class MyClass {
public:MyClass() {// 自定义默认构造函数}MyClass(int value) {// 自定义有参构造函数}MyClass(const MyClass& other) {// 自定义拷贝构造函数}~MyClass() {// 自定义析构函数}
};

        通过理解这些规则,可以更好地控制对象的生命周期,避免潜在的内存泄漏和其他问题。 

后续我将逐步整合,收藏不迷路!!!大家感兴趣,也可以先看看我之前的博客!!!

C++对象模型和this指针

C++友元

C++运算符重载

C++继承

C++多态

C++文件

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

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

相关文章

超声波清洗机哪家好?家用超声波眼镜清洗机推荐

超声波清洗机现在已经成为了很多家庭的新宠&#xff0c;它能够帮助我们轻松解决日常生活中的清扫烦恼。但是&#xff0c;面对市面上品种繁多的清洗机产品&#xff0c;我们该如何选择一款适合自己的呢?毕竟不同的品牌和型号&#xff0c;在清洗效果、噪音水平、除菌能力等方面都…

RHCE-autofs自动挂载

要求 一、在主机上提供web&#xff0c;dns服务 服务端 IP&#xff1a;172.25.250.131/24 dns&#xff1a;172.25.250.131 [rootlocalhost ~]# cd /etc/httpd/conf.d[rootlocalhost conf.d]# vim vhost.conf [rootlocalhost conf.d]# mkdir /nfs/rhce -p[rootlocalhost conf…

雪深监测站的工作原理

TH-TS200雪深监测站是一种用于测量和记录雪层深度的设备&#xff0c;它在气象观测、交通管理、防灾减灾、水源管理等多个领域发挥着重要作用。雪深监测用来监测雪深的设备。它通过各种传感器和测量设备&#xff0c;如超声波测距仪、激光测距仪、压力传感器等&#xff0c;获取雪…

若依安装和初始化教程(傻瓜教程 一步一步走)

1、若依的安装&#xff1a; 1、找到若依官方网站并选择若依的前后端分离版本 2、点击克隆 然后选择http进行复制 3、打开idea 如果有打开的项目就先关闭项目&#xff0c;然后就会自动弹出下面第二张图片&#xff0c;接着按照流程走就可以 到此若依的下载就成功了 2、若依项目…

如何判断代码是否是在UPDATE TASK的Session中执行?

1. 背景 有时我们想控制ABAP代码在UPDATE TASK中的逻辑&#xff0c;例如某些逻辑执行&#xff0c;某些逻辑不执行。 那么&#xff0c;我们应该如何判断当前代码运行的环境呢&#xff1f;也即&#xff0c;怎么知道一段运行时代码是运行在当前的ABAP session中&#xff0c;还是…

IDEA设置代码提示忽略大小写

一、设置代码提示为忽略大小写 IDEA代码提示默认是区分大小写的&#xff0c;设置为提示忽略大小写&#xff1a; Setting——Editor——Code Completion 如图

智慧金融-数据可视化

智慧金融-数据可视化 导入所需的库 import numpy as np import numpy_financial as npf import matplotlib.pyplot as plt from pylab import mpl mpl.rcParams[font.sans-serif][FangSong] mpl.rcParams[axes.unicode_minus]False单图曲线图 r 0.05 # 贷款的年利率 n 30…

字符串哈希详解,单hash,双hash,滚动哈希

一、字符串哈希 1.1 基本概念 字符串哈希 将不同的字符串映射成不同的整数。 思想&#xff1a;将字符串映射成一个 p进制数字。 我们定义如下哈希函数&#xff1a; h a s h ( s ) ∑ i 1 n s [ i ] p n − i ( m o d M ) 其中 s 为长度为 n 的字符串&#xff0c;下标从…

【考研408操作系统】最容易理解的知识体系-文件管理-面向人类管理

苏泽 “弃工从研”的路上很孤独&#xff0c;于是我记下了些许笔记相伴&#xff0c;希望能够帮助到大家 我将以全新的视角用两篇文章梳理完考研计算机当中关于“文件管理”这个部分的考点的所有内容 以下是我整理的知识点思维导图 目录 我将以全新的视角用两篇文章梳理完考研…

代码随想录算法训练营第三十天

56. 合并区间 这道题跟452. 用最少数量的箭引爆气球 (opens new window)和 435. 无重叠区间 (opens new window)都是一个套路。 回了上面两个这道题并不难 这题主要就是发现重叠后更新一下当前元素的起始范围 if (intervals[i][0] < intervals[i-1][1]) {intervals[i][0…

和鲸101计划夏令营火热进行中!北中医助阵医学数据探索

上周&#xff0c;和鲸社区 2024 夏令营已经正式开营&#xff01; 从 2021 年开始&#xff0c;和鲸社区在每年暑假期间都会为大家提供集中化、系统化的数据科学相关的技能实践和培训&#xff0c;每年都有几千名同学借此机会积累宝贵的实战经验&#xff0c;丰富个人简历作品&…

DR模式介绍

DR模式 lvs的三种模式 nat&#xff1a;地址转换 DR模式&#xff1a;直接路由模式 tun&#xff1a;隧道模式 DR模式的特点 调度器在整个lvs集群当中是最重要的&#xff0c;在nat模式下&#xff0c;即负责接受请求&#xff0c;同时根据负载均衡的算法转发流量&#xff0c;响…

2025 百度提前批校招内推

百度2025校园招聘内推开始啦&#xff0c;被推荐人可以免笔试直接面试&#xff0c;提前批结果不影响校招&#xff0c;机会1&#xff0c;还可直推心仪部门&#xff0c;可扫描下面二维码或点击链接进行投递&#xff0c;快来投递你心仪的职位吧&#xff08; 网申链接地址 &#xff…

Linux 04:进程概念

1. 操作系统(Operator System) 概念 任何计算机系统都包含一个基本的程序集合&#xff0c;称为操作系统(OS)。笼统的理解&#xff0c;操作系统包括&#xff1a; 内核&#xff08;进程管理&#xff0c;内存管理&#xff0c;文件管理&#xff0c;驱动管理&#xff09;。其他程序…

微信小程序毕业设计-高校校园交友系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

仕考网:公务员考试面试时间一般多长?

公务员考试主要分为笔试与面试两个阶段&#xff0c;其中面试是笔试通过的下一关&#xff0c;面试的具体安排通常由相关考试机构或招录单位负责发布并通知考生。 公务员面试的持续时间一般在30分钟至1小时之间&#xff0c;具体时长可能因地区和招录单位的不同而有所变化。常见的…

分布式锁理解

介绍分布式锁&#xff0c;我觉得从项目的背景入手把 在伙伴匹配系统中&#xff0c;我创建了一个定时任务&#xff0c;做为缓存预热的手段 这个具体原因在Redis-CSDN博客 接下来切入正题&#xff1a; 想象每个服务器都有一个定时任务&#xff0c;都要对数据库或者缓存进行操…

Coze触发器:触发任务的Python接口源码

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 Coze触发器 📒📝 触发器接口源码⚓️ 相关链接 ⚓️📖 介绍 📖 自动化,一个在现代软件开发中不可或缺的概念,它让我们的生活和工作变得更加高效。Coze也支持定时任务/触发任务,通过触发器,我们可以更自由的控制Bot去…

【cocos creator】2.x,伪3d拖拽,45度视角,60度视角,房屋装扮

伪3d拖拽&#xff0c;45度视角,60度视角 工程下载&#xff1a;&#xff08;待审核&#xff09; https://download.csdn.net/download/K86338236/89530812 dragItem2.t s import mapCreat2 from "./mapCreat2";const { ccclass, property } cc._decorator; /*** 拖拽…

【web]-信息收集-空白页面

打开是一张图 查看源码&#xff0c;发现就一个链接是有用信息&#xff0c;用目录扫描工具&#xff0c;没有发现有价值的信息。 F12&#xff0c;查看请求和相应信息&#xff0c;在响应头中发现了信息。 还有一个小技巧&#xff1a;点击手机图标&#xff0c;可以切换到手机模式中…