【C++系列(合集)】特性多又复杂?不存在!——这篇C++大全直接干碎(超级大全,精讲)(一)

简介: 【C++系列(合集)】特性多又复杂?不存在!——这篇C++大全直接干碎(超级大全,精讲)

一.缺省函数

运用场景:


例:在通讯录项目时,可以省去初始化函数,通过参数的变化可以选择实现初始化/增删查改。

图示:


(图中的StackInit函数就是缺省函数,当我们传入栈的地址时且没有传入第二个参数时,它会默认传入另一个参数4)

image.png

注意事项:


只有参数的后部参数才是可以缺省,即缺省函数参数后不可以再跟正常参数

缺省函数的定义和声明:


缺省函数只能放在函数声明中——编译器必须在使用函数之前知道缺省值

二.命名空间域

引入:在实际运用代码的过程中,可能存在局部变量之间命名冲突/库与局部变量命名之间相互冲突的情况,因而我们可以在局部域全局域之外设置一个区域:命名空间域。要使用时通过 a)展开命名空间域 / b)指定访问命名空间域 来实现。


程序在编译时的优先顺序:局部域->全局域->展开的命名空间域  


image.png

image.png

三.函数重载

【函数重载】


是函数的一种特殊情况,C++允许在同一作用域中声名几个功能类似的同名函数显著特征:这些同名函数的形参列表(个数,类型,类型顺序)不同

注意点:对  返回值  没有要求 ,注意声明!(例:缺省函数)


图示:(注意函数声明时,是否存在缺省函数等问题)

image.png

四.引用

1.含义与特点

引用,即取别名。它的最大特点是编译器不会为引用变量而开辟空间,他们共用同一块空间。


2.引用和指针的区别(主要)

1.引用使用时必须要初始化。


2.引用在初始化时引用一个实体后,不能再次引用其他实体,只能赋值。


3.引用使用起来更安全。


图示:

image.png

3.引用的实际使用


一.引用作为参数

作为输出型参数时,面对大对象/深拷贝对象由于不用另外开辟空间拷贝,可以提高效率


二.引用作为返回值  

1.适用场景

2.修改返回值+获取返回值 (使通讯录代码更简洁)


1.不适用场景:

image.png

适用场景:(静态区栈帧不销毁)

image.png

2.实际应用

  • 在通讯录中,用传统的方法,需要“查找"到对应pos位置后再“修改”
  • 而运用“引用作为返回值”,可直接对查找到的值进行修改。

image.png

原本操作:

image.png

改进后操作:

image.png

3.引用过程中的权限问题(平移,缩小,放大)

首先我们要知道,临时变量是具有常性,const 修饰的类型也具有常性,static的数据存储在静态区同样具备常性。

const和static的权限理论上平级,而临时变量的权限低于二者。

只能存在权限平级和权限缩小的情况,不能存在权限放大的情况。通俗而言:权限低的不能给权限(常性)强的取别名。

权限相关知识点:【权限等级较高的是const和具有常属性的量,权限较低的是普通数据】


权限高的或平级的可以给另一量取别名/取地址(权限的缩小和平移)

权限低的不能给另一量取别名/取地址(权限的放大)

图示:

image.png

1.平级和权限缩小的情况

image.png

image.png

2.权限平移情况

image.png

3.权限放大情况

image.png

image.png

PS:const原则上不能修改,但是可以通过找到其空间直接修改。(指针/别名)

五.C++中的NULL与空指针区别

  • 在C++中,NULL表示“ 0 ”,实际是一个宏。
  • 在C++中要表示 空指针,使用 nullptr
  • 图示:

image.png

六. 内联函数

1.内敛函数适用“短小,使用频繁的函数”

当实现加法功能时,需要频繁调用加法函数,调用函数的过程中包含着频繁地开辟栈帧空间和关闭空间,会让程序运行速度变低。而解决类似问题可以使用“宏函数”,但是宏函数面临——易出错(需要括号确保直接替换后不受影响)。在这时使用内联函数,不会频繁开辟空间,大大提高了程序的运行速度。顶中顶有没有!!但别急,它也还有缺点呢~

2.内敛函数的缺陷/特点

内联函数的本质是通过牺牲空间换时间,运用内联函数程序的运行速度大大提升,但于此同时程序的大小也会急剧增大。因此面对一些逻辑稍微复杂的运算(循环/递归)便会大大造成冗余。

inline对于编译器也仅仅是一个建议,最终是否成为inline,编译器自己会判断。

且默认debug状态下,inline不会起作用。

3.内联函数声明和定义必须要放在一起的原因  

编译器一旦把某个函数作为内联函数处理,就会在其调用的位置展开,即该函数没有地址,源文件编译后不会形成符号表,没有链接冲突。同时也不能在其他源文件中调用,故一般都是直接在源文件中定义内联函数——可以在同一个项目不同的源文件中定义函数名相同但实现不同的inline函数。

七.类

1.C++兼容C,C语言中的结构体strcut也算是一种类,是public(公有)的,可以被类外直接访问。


2.类中的函数默认是内联函数,具体是否是内联函数编译器会判断。如果将其定义和声名分开,即类放在.h文件,定义函数放在.cpp文件,函数不为内联函数。


1.类的组成与计算类的大小(含结构体内存对齐规则)

类由访问限定符划分,类中既有成员变量,又有成员函数

image.png

image.png

计算类的大小,只用考虑成员变量的大小

例如:上图中,类的大小为8字节

image.png

PS:内存对齐,本质上是牺牲空间换取效率。通过调整默认对齐数可以对这一过程进行动态调整。


2. 空类的大小

没有成员变量的类对象,需要1byte,是为了占位,表示对象存在


3. This指针

This指针本质是形参,所以this指针是和普通参数一样存在函数调用的栈帧里


1.编译器对This指针的处理本质——不允许修改this,但是允许修改this指向的值  

void Print(Date* const this)
{
  cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
}

2.This不能在形参和实参显示传递,但是可以在函数内部显示使用

void Print()
{
   // this不能在形参和实参显示传递,但是可以在函数内部显示使用
   //this = nullptr;
   cout << this << endl;
   cout << this->_year << "-" << _month << "-" << _day << endl;
}

3.例题对比:传入空指针时,this的运作状况

重点注意:p->Print()并非解引用操作

image.png

注意点:Print的地址不在对象中

image.png

4.const成员/成员函数

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this 指针表明在该成员函数中不能对类的任何成员进行修改

图示:

image.png

一.用const修饰this指针的好处——含权限知识点

PS:权限知识点在下方

用const修饰this指针的好处:普通对象const对象都能调用

图示:

image.png

权限相关知识点:【权限等级较高的是const和具有常属性的量,权限较低的是普通数据

  • 权限高的或平级的可以给另一量取别名/取地址(权限的缩小平移
  • 权限低的不能给另一量取别名/取地址(权限的放大

图示:

image.png

二.能否所有的成员函数都加上const?

答案:不是的,要修改成员变量的函数不能加。


三.几个的使用场景

请思考下面的几个问题:


1. const对象可以调用非const成员函数吗?no

2. 非const对象可以调用const成员函数吗?yes

3. const成员函数内可以调用其它的非const成员函数吗?no

4. 非const成员函数内可以调用其它的const成员函数吗?yes

5.static静态成员

一.静态成员基本知识

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。


使用要点:静态成员变量一定要在类外进行初始化


二.静态成员特性

静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区

静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明

类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问

静态成员函数没有隐藏的this指针,不能访问任何非静态成员

静态成员也是类的成员,受public、protected、private 访问限定符的限制

三.静态成员函数和非静态成员函数的调用关系

请思考下面的几个问题:


静态成员函数可以调用非静态成员函数吗?no(无this指针)

非静态成员函数可以调用类的静态成员函数吗?  yes


相关文章
|
3月前
|
编译器 程序员 定位技术
C++ 20新特性之Concepts
在C++ 20之前,我们在编写泛型代码时,模板参数的约束往往通过复杂的SFINAE(Substitution Failure Is Not An Error)策略或繁琐的Traits类来实现。这不仅难以阅读,也非常容易出错,导致很多程序员在提及泛型编程时,总是心有余悸、脊背发凉。 在没有引入Concepts之前,我们只能依靠经验和技巧来解读编译器给出的错误信息,很容易陷入“类型迷路”。这就好比在没有GPS导航的年代,我们依靠复杂的地图和模糊的方向指示去一个陌生的地点,很容易迷路。而Concepts的引入,就像是给C++的模板系统安装了一个GPS导航仪
139 59
|
2月前
|
安全 编译器 C++
【C++11】新特性
`C++11`是2011年发布的`C++`重要版本,引入了约140个新特性和600个缺陷修复。其中,列表初始化(List Initialization)提供了一种更统一、更灵活和更安全的初始化方式,支持内置类型和满足特定条件的自定义类型。此外,`C++11`还引入了`auto`关键字用于自动类型推导,简化了复杂类型的声明,提高了代码的可读性和可维护性。`decltype`则用于根据表达式推导类型,增强了编译时类型检查的能力,特别适用于模板和泛型编程。
27 2
|
3月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(三)
【C++】面向对象编程的三大特性:深入解析多态机制
|
3月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(二)
【C++】面向对象编程的三大特性:深入解析多态机制
|
3月前
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(一)
【C++】面向对象编程的三大特性:深入解析多态机制
|
3月前
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
4月前
|
编译器 C++ 计算机视觉
C++ 11新特性之完美转发
C++ 11新特性之完美转发
61 4
|
4月前
|
Java C# C++
C++ 11新特性之语法甜点1
C++ 11新特性之语法甜点1
39 4
|
3月前
|
C++
C++ 20新特性之结构化绑定
在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。
46 0
|
4月前
|
安全 程序员 编译器
C++ 11新特性之auto和decltype
C++ 11新特性之auto和decltype
49 3