C++语言基础篇(二)

简介: C++语言基础篇(二)

目录


1、C++ 中内存分配情况


2、C++ 中的指针参数传递和引⽤参数传递


3、C++ 中 const 和 static 关键字(定义,⽤途)


作⽤⼀:


作⽤⼆:


作⽤三:


作⽤四:


作⽤五:


1、C++ 中内存分配情况

栈:由编译器管理分配和回收,存放局部变量和函数参数。 堆:由程序员管理,需要⼿动 new malloc delete free 进⾏分配和回收,空间较⼤,但可能会出现内存泄漏和空闲 碎⽚的情况。 全局/静态存储区:分为初始化和未初始化两个相邻区域,存储初始化和未初始化的全局变量和静态变量。 常量存储区:存储常量,⼀般不允许修改。 代码区:存放程序的⼆进制代码。


2、C++ 中的指针参数传递和引⽤参数传递

指针参数传递本质上是值传递,它所传递的是⼀个地址值。值传递过程中,被调函数的形式参数作为被调函数的局 部变量处理,会在栈中开辟内存空间以存放由主调函数传递进来的实参值,从⽽形成了实参的⼀个副本(替身)。 值传递的特点是,被调函数对形式参数的任何操作都是作为局部变量进⾏的,不会影响主调函数的实参变量的值 (形参指针变了,实参指针不会变)。 引⽤参数传递过程中,被调函数的形式参数也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数 放进来的实参变量的地址。被调函数对形参(本体)的任何操作都被处理成间接寻址,即通过栈中存放的地址访问 主调函数中的实参变量(根据别名找到主调函数中的本体)。因此,被调函数对形参的任何操作都会影响主调函数 中的实参变量。


引⽤传递和指针传递是不同的,虽然他们都是在被调函数栈空间上的⼀个局部变量,但是任何对于引⽤参数的处理 都会通过⼀个间接寻址的⽅式操作到主调函数中的相关变量。⽽对于指针传递的参数,如果改变被调函数中的指针 地址,它将应⽤不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量(地址),那就 得使⽤指向指针的指针或者指针引⽤。


从编译的⻆度来讲,程序在编译时分别将指针和引⽤添加到符号表上,符号表中记录的是变量名及变量所对应地 址。指针变量在符号表上对应的地址值为指针变量的地址值,⽽引⽤在符号表上对应的地址值为引⽤对象的地址值 (与实参名字不同,地址相同)。符号表⽣成之后就不会再改,因此指针可以改变其指向的对象(指针变量中的值 可以改),⽽引⽤对象则不能修改。


3、C++ 中 const 和 static 关键字(定义,⽤途)

static 作⽤:控制变量的存储⽅式和可⻅性。


作⽤⼀:

修饰局部变量:⼀般情况下,对于局部变量在程序中是存放在栈区的,并且局部的⽣命周期在包含语句块 执⾏结束时便结束了。但是如果⽤ static 关键字修饰的话,该变量便会存放在静态数据区,其⽣命周期会⼀直延续 到整个程序执⾏结束。但是要注意的是,虽然⽤ static 对局部变量进⾏修饰之后,其⽣命周期以及存储空间发⽣了 变化,但其作⽤域并没有改变,作⽤域还是限制在其语句块。


作⽤⼆:

修饰全部变量:对于⼀个全局变量,它既可以在本⽂件中被访问到,也可以在同⼀个⼯程中其它源⽂件被 访问(添加 extern进⾏声明即可)。⽤ static 对全局变量进⾏修饰改变了其作⽤域范围,由原来的整个⼯程可⻅变成 了本⽂件可⻅。


作⽤三:

修饰函数:⽤ static 修饰函数,情况和修饰全局变量类似,也是改变了函数的作⽤域。


作⽤四:

修饰类:如果 C++ 中对类中的某个函数⽤ static 修饰,则表示该函数属于⼀个类⽽不是属于此类的任何 特定对象;如果对类中的某个变量进⾏ static 修饰,则表示该变量以及所有的对象所有,存储空间中只存在⼀个副 本,可以通过;类和对象去调⽤。


(补充:静态⾮常量数据成员,其只能在类外定义和初始化,在类内仅是声明⽽已。)


作⽤五:

类成员/类函数声明 static


函数体内 static 变量的作⽤范围为该函数体,不同于 auto 变量,该变量的内存只被分配⼀次,因此其值在下 次调⽤时仍维持上次的值;


在模块内的 static 全局变量可以被模块内所⽤函数访问,但不能被模块外其它函数访问;


在模块内的 static 函数只可被这⼀模块内的其它函数调⽤,这个函数的使⽤范围被限制在声明它的模块内;


在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有⼀份拷⻉;


在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因⽽只能访问类的 static 成员变 量。


static 类对象必须要在类外进⾏初始化,static 修饰的变量先于对象存在,所以 static 修饰的变量要在类外初 始化; 由于 static 修饰的类成员属于类,不属于对象,因此 static 类成员函数是没有 this 指针,this 指针是指向本 对象的指针,正因为没有 this 指针,所以 static 类成员函数不能访问⾮ static 的类成员,只能访问 static修饰 的类成员;


static 成员函数不能被 virtual 修饰,static 成员不属于任何对象或实例,所以加上 virtual 没有任何实际意 义;静态成员函数没有 this 指针,虚函数的实现是为每⼀个对象分配⼀个 vptr 指针,⽽ vptr 是通过 this 指 针调⽤的,所以不能为 virtual;虚函数的调⽤关系,this->vptr->ctable->virtual function。


const 关键字:含义及实现机制


const 修饰基本类型数据类型:基本数据类型,修饰符 const 可以⽤在类型说明符前,也可以⽤在类型说明符后, 其结果是⼀样的。在使⽤这些常量的时候,只要不改变这些常量的值即可。


const 修饰指针变量和引⽤变量:如果 const 位于⼩星星的左侧,则 const 就是⽤来修饰指针所指向的变量,即指 针指向为常量;如果 const 位于⼩星星的右侧,则 const 就是修饰指针本身,即指针本身是常量。


const 应⽤到函数中:作为参数的 const 修饰符:调⽤函数的时候,⽤相应的变量初始化 const 常量,则在函数体 中,按照 const 所修饰的部分进⾏常量化,保护了原对象的属性。 [注意]:参数 const 通常⽤于参数为指针或引⽤ 的情况; 作为函数返回值的 const 修饰符:声明了返回值后,const 按照"修饰原则"进⾏修饰,起到相应的保护作 ⽤。


const 在类中的⽤法:const 成员变量,只在某个对象⽣命周期内是常量,⽽对于整个类⽽⾔是可以改变的。因为 类可以创建多个对象,不同的对象其 const 数据成员值可以不同。所以不能在类的声明中初始化 const 数据成员, 因为类的对象在没有创建时候,编译器不知道 const 数据成员的值是什么。const 数据成员的初始化只能在类的构 造函数的初始化列表中进⾏。const 成员函数:const 成员函数的主要⽬的是防⽌成员函数修改对象的内容。要注 意,const 关键字和 static 关键字对于成员函数来说是不能同时使⽤的,因为 static 关键字修饰静态成员函数不含 有 this 指针,即不能实例化,const 成员函数⼜必须具体到某⼀个函数。


const 修饰类对象,定义常量对象:常量对象只能调⽤常量函数,别的成员函数都不能调⽤。


补充:const 成员函数中如果实在想修改某个变量,可以使⽤ mutable 进⾏修饰。成员变量中如果想建⽴在整个类 中都恒定的常量,应该⽤类中的枚举常量来实现或者 static const。


C ++ 中的 const类成员函数(⽤法和意义)


常量对象可以调⽤类中的 const 成员函数,但不能调⽤⾮ const 成员函数; (原因:对象调⽤成员函数时,在形 参列表的最前⾯加⼀个形参 this,但这是隐式的。this 指针是默认指向调⽤函数的当前对象的,所以,很⾃然,


this 是⼀个常量指针 test * const,因为不可以修改 this 指针代表的地址。但当成员函数的参数列表(即⼩括号) 后加了 const 关键字(void print() const;),此成员函数为常量成员函数,此时它的隐式this形参为 const test * const,即不可以通过 this 指针来改变指向对象的值。


⾮常量对象可以调⽤类中的 const 成员函数,也可以调⽤⾮ const 成员函数。

相关文章
|
2月前
|
C++
C++ 语言异常处理实战:在编程潮流中坚守稳定,开启代码可靠之旅
【8月更文挑战第22天】C++的异常处理机制是确保程序稳定的关键特性。它允许程序在遇到错误时优雅地响应而非直接崩溃。通过`throw`抛出异常,并用`catch`捕获处理,可使程序控制流跳转至错误处理代码。例如,在进行除法运算或文件读取时,若发生除数为零或文件无法打开等错误,则可通过抛出异常并在调用处捕获来妥善处理这些情况。恰当使用异常处理能显著提升程序的健壮性和维护性。
58 2
|
2月前
|
算法 C语言 C++
C++语言学习指南:从新手到高手,一文带你领略系统编程的巅峰技艺!
【8月更文挑战第22天】C++由Bjarne Stroustrup于1985年创立,凭借卓越性能与灵活性,在系统编程、游戏开发等领域占据重要地位。它继承了C语言的高效性,并引入面向对象编程,使代码更模块化易管理。C++支持基本语法如变量声明与控制结构;通过`iostream`库实现输入输出;利用类与对象实现面向对象编程;提供模板增强代码复用性;具备异常处理机制确保程序健壮性;C++11引入现代化特性简化编程;标准模板库(STL)支持高效编程;多线程支持利用多核优势。虽然学习曲线陡峭,但掌握后可开启高性能编程大门。随着新标准如C++20的发展,C++持续演进,提供更多开发可能性。
56 0
|
6天前
|
算法 C++
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
12 5
|
11天前
|
存储 编译器 C语言
深入计算机语言之C++:类与对象(上)
深入计算机语言之C++:类与对象(上)
|
11天前
|
存储 分布式计算 编译器
深入计算机语言之C++:C到C++的过度-2
深入计算机语言之C++:C到C++的过度-2
|
11天前
|
编译器 Linux C语言
深入计算机语言之C++:C到C++的过度-1
深入计算机语言之C++:C到C++的过度-1
|
1月前
|
JavaScript 前端开发 测试技术
一个google Test文件C++语言案例
这篇文章我们来介绍一下真正的C++语言如何用GTest来实现单元测试。
16 0
|
2月前
|
编译器 C++ 容器
C++语言的基本语法
想掌握一门编程语言,第一步就是需要熟悉基本的环境,然后就是最重要的语法知识。 C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。 对象 - 对象具有状态和行为。例如:一只狗的状态 - 颜色、名称、品种,行为 - 摇动、叫唤、吃。对象是类的实例。 类 - 类可以定义为描述对象行为/状态的模板/蓝图。 方法 - 从基本上说,一个方法表示一种行为。一个类可以包含多个方法。可以在方法中写入逻辑、操作数据以及执行所有的动作。 即时变量 - 每个对象都有其独特的即时变量。对象的状态是由这些即时变量的值创建的。 完整关键字
55 2
|
3月前
|
前端开发 编译器 程序员
协程问题之为什么 C++20 的协程代码比其他语言的协程 demo 长很多如何解决
协程问题之为什么 C++20 的协程代码比其他语言的协程 demo 长很多如何解决
|
4月前
|
存储 Java C#
C++语言模板类对原生指针的封装与模拟
C++|智能指针的智能性和指针性:模板类对原生指针的封装与模拟