[C++]-C++前期概念

目录

【C++概述】 

1.C++的编程思想

 2.C++面向对象的三大特性

【C++的作用域运算符和命名空间】

1. ::运算符

 2. 命名空间

1.命名空间的创建

2.命名空间的一些注意事项

2.1命名空间只能定义在全局中

2.2命名空间嵌套

扫描二维码关注公众号,回复: 17268560 查看本文章

2.3命名空间成员追加问题

2.4命名空间中函数成员声明和实现分离

3.无名命名空间

4.命名空间名字的修改

5.using声明命名空间可用成员

6.using声明整个命名空间有效

【类型增强】

1.C++形参必须有类型

2.C++和C语言结构体的区别

3.三目运算符增强

4.const的类型增强

4.1 C++对const进行的优化

【引用】

1.引用的定义

2.引用作为函数参数

3.引用作为函数的返回值

 4.常引用

【内联函数】

1.内联函数和宏函数的区别

2.内联函数注意事项

【函数重载】

1.函数重载的条件

2.函数重载的底层实现

【缺省参数】

【占位参数】


【C++概述】 

1.C++的编程思想

C++是编程思想为面向对象、泛型编程的语言。C++和C在编程思想上,最主要的区别就是

C的编程思想是面向过程编程思想

C++的编程思想最主要是面向对象的编程思想

这两者听起来似乎有点抽象,简单的说,C语言的思想就是现在干什么、下一步干什么、在下一步干什么,是通过调用API一步步实现的,而C++是这个对象现在干什么、这个对象下一步干什么,这个对象在下一步干什么

 2.C++面向对象的三大特性

C++面向对象具有如下的三大特性:

封装:把相同属性的数据和函数封装为一个类,加以权限区分,外界只能通过提供的公共方法访问类中私有数据。

继承:主要体现在类与类之间,假如A类继承了B类,那么A拥有B的除了私有数据外的所有数据和方法。

多态:一个API可以提供多种功能。



【C++的作用域运算符和命名空间】

1. ::运算符

C++中添加了::运算符,主要是用来解决命名空间以及命名污染的问题,防止实际开发中多个相同变量名的出现,如果直接使用::访问的是全局变量的数据。

 2. 命名空间

使用关键字namespace可以创建命名空间,命名空间可以对符号常量、变量、函数、结构、枚举、类以及对象等等进行封装,使用时通过作用域进行访问,很好的避免了命名污染

1.命名空间的创建

需要注意的是命名空间后面是不带 ; 的,不是结构体

namespace 空间名
{

    ........

}

2.命名空间的一些注意事项

2.1命名空间只能定义在全局中

2.2命名空间嵌套

2.3命名空间成员追加问题

假如我们在开头定义了一个命名空间,中间已经完成了很多行代码,就算我们想往命名空间里面添加新的成员,那么我们也没有必要专门移动到开头的位置,可以直接添加,格式就相当于定义命名空间

//假如这里要往命名空间添加成员b

namespace A
{
    int a = 10;
}


//..............


namespace A
{
    int b = 10;
}

2.4命名空间中函数成员声明和实现分离

在命名空间中我们可以定义函数成员,但是那样可能会导致命名空间看起来比较臃肿,我们可以命名空间内声明函数,在外部实现,但是需要添加命名空间作用域

namespace A {
    int a = 10;
    void aFun(void);
}
void A::aFun(void)
{
    cout << "A fun" << endl;
}

3.无名命名空间

在C语言中,我们对全局变量加static修饰既可以防止该变量在外部文件被使用,那么C++中我们要怎么实现这个功能呢,可以使用无名命名空间,它的访问和全局变量访问是一样的,都是以 :: 运算符访问,唯一不同的就是,无名命名空间中的变量是只能在本文件中使用

//相当于C语言中定义静态全局变量
namespace  {
    int a = 10;
}

4.命名空间名字的修改

namespace A
{

}

//把命名空间A的名字修改为B
namespace B = A;

5.using声明命名空间可用成员

命名空间是独立出来的,如果我们不想通过添加作用域来访问命名空间的成员的话,我们可以使用using来声明命名空间里哪些成员是可用的。

 从如下现象可见,声明命名空间里的某个成员可用是相当于在函数内部定义一个同名变量(经过实践发现这个变量似乎是和命名空间里变量有链接关系,两者改变互相影响),所以无法再次引用另一个命名空间的同名变量。

6.using声明整个命名空间有效

如果想要把整个命名空间都声明有效,只需要using namespace 空间名,即可。不管是在函数内部还是在函数外部,都是相当于把命名空间里的成员全部定义为全局变量(实际上不是),所以全局区不可以在定义同名变量,但是函数内部可以。

 关于命名空间using声明变量重名的问题,如果声明在全局区是重新定义一个变量,和原本全局区的不是同一块空间,如果不去访问则可以编译通过。但是如果是函数内部如果出现同名问题则是同一块空间,编译无法通过



【类型增强】

1.C++形参必须有类型

如下代码在C语言下是可以编译通过的,但是在C++下无法通过,因为形参没有类型

#include <iostream>

using namespace std;

void fun(i)
{
    cout << i << endl;
}

int main(int argc, char *argv[])
{
    fun(20);
    return 0;
}

2.C++和C语言结构体的区别

假如一个结构体类型为 struct STU

那么

C在定义的时候必须 struct STU stu1,而C++可以省略前面的struct

还有一个最主要的区别,C++的结构体中可以有函数成员,而C不行

3.三目运算符增强

C和C++三目运算符最主要的区别就是,C语言返回的是一个常量,是只读的,但是C++返回的是一个引用,是可以修改的

4.const的类型增强

4.1 C++对const进行的优化

这里我们按照const修饰的变量的被赋值对象的两种情况来进行讨论

1.当右值为常量

如果const修饰变量的右值为一个常量,那么系统不会立即为这个变量开辟空间,而是将其放置于符号常量表中,用这个符号表示这个常量,只有在对其取地址的时候才会开辟空间

2.右值为变量或者自定义数据类型

如果右值为自定义类型或者变量,那么不会存在符号常量表,而是直接开辟空间,并且修饰变量为只读。

其实这也很好理解,如果存在符号常量表,那么一个符号要怎么代表一个变量呢,或者一个符号怎么代表一个自定义类型比如说结构体呢



【引用】

1.引用的定义

引用的本质就是给变量取一个别名

 引用必须初始化,并且只能在初始化的时候赋值

不管是定义引用还是指针,只要遵循如下上下替换的方法,不管是什么类型都可以很容易的定义出来

&别名

给哪个变量取别名就定义哪个变量

从上往下整体替换

&b

int a

int (&b) = a

//给普通变量取别名
int a = 10;
int &b = a;

//给数组取别名
char a[100] = "";
char (&b)[100] = a;

//指针变量取别名
int *a = NULL;
int *(&b) = a;

//给函数取别名
void a(void);
void (&b)(void) = a;

2.引用作为函数参数

引用作为函数的参数可以完成像指针那样的在函数内部修改外部的值的操作

但是相比于使用指针,引用最重要的是可以节约形参的空间,因为引用是不占用空间的

void swap(int& a, int& b)
{
    int temp = a;
    a = b;
    b = temp;
}

3.引用作为函数的返回值

引用也可以作为函数的返回值,但是需要注意的是该变量的生命周期,如果在函数结束后,该变量生命周期已经结束了,那么会造成引用访问的是一块已经被释放的空间

 4.常引用

常引用最广泛的应用于,防止函数内部修改函数外部传进来的值



【内联函数】

C++中为了解决宏函数出现的无区分作用域的情况,使用内联函数,这两者主要实现的功能还是很相似的,都是在合适的地点进行展开

内联函数在编译阶段进行展开,将内联函数中的函数体替换到内联函数的地点,减少函数调用时候的开销

内联函数必须在定义的时候加inline进行修饰,而不能在声明的时候加inline

//声明的时候不加inline修饰
void func(int a)

//定义的时候加inline
inline void func(int a)
{
    
}

1.内联函数和宏函数的区别

内联函数和宏函数均会在特定的时候进行展开,避免函数调用的开销

内联函数参数有类型,可以保证参数完整性

宏函数参数没有类型,不可以可以保证参数完整性

内联函数在编译阶段展开

宏函数在预处理阶段展开

内联函数有作用域的限制

宏函数没有作用域限制

2.内联函数注意事项

内联函数存在以下条件

        不能有循环

        不能有过多的判断

        不能有过大的函数体

        不能对内联函数取地址(因为编译阶段已经替换)

即使加了inline修饰,也不一定是内联函数。不加inline修饰,也可能是内联函数,这主要是编译器判断,合适的函数都会是内联函数减少函数调用开销



【函数重载】

函数重载是C++多态特性的体现,一个函数可以有多种功能

1.函数重载的条件

函数重载具有如下条件

函数名相同的情况下:形参个数不同、形参类型不同、形参顺序不同

2.函数重载的底层实现

函数名就是函数的入口地址,从我们的角度看虽然函数名还是相同的,但是底层会进行优化,不是同一个入口



【缺省参数】

缺省参数就是在定义或者声明的时候,对形参赋值,如果使用者没有对该形参赋值,那么该形参就为默认值

 注意

形参中,一个缺省参数的右边的所有参数都必须为缺省参数



【占位参数】

占位参数的形式如下,其最主要就用于运算符重载中++运算符区分前置加加和后置加加

void fun(int a , int)
{
    
}

右边的int即为占位参数,由于没有变量可以接受,所以即使外界传入了参数函数内部也无法使用。

猜你喜欢

转载自blog.csdn.net/m0_72372635/article/details/131918692