**C++总结小记**

前些天,写代码发现有些基础知识都忘的差不多了,有段时间么有用了,花了些时间查了些资料后,做了个总结:
1、C++中构造函数和析构函数调用顺序:

构造函数:

基类构造函数-》对象成员构造函数-》派生类构造函数。。。派生类析构函数-》对象成员析构函数-》基类析构函数;

虚函数必须是类的成员函数,其中,静态成员函数和构造函数不能定义为虚函数,析构函数可以;

特例:

1、静态对象:在所在的定义文件结束时析构;

2、全局对象:在程序结束后析构;

3、对象成员:先析构类对象,后析构数据成员;

2、const关键字:

#const修饰变量:

1 #include
2 using namespace std;
3 int main(){
4 int a1=3; //non-const data
5 const int a2=a1; //const data
6
7 int * a3 = &a1; //non-const data,non-const pointer
8 const int * a4 = &a1; //const data,non-const pointer
9 int * const a5 = &a1; //non-const data,const pointer
10 int const * const a6 = &a1; //const data,const pointer
11 const int * const a7 = &a1; //const data,const pointer
12
13 return 0;
14 }
(1)只有一个const,如果const位于*左侧,表示指针所指数据是常量,不能通过解引用修改该数据;

指针本身是变量,可以指向其他的内存单元。

(2)只有一个const,如果const位于*右侧,表示指针本身是常量,不能指向其他内存地址;

指针所指的数据可以通过解引用修改。

(3)两个const,*左右各一个,表示指针和指针所指数据都不能修改。

#const修饰形参:传递过来的参数在函数内不可以改变,与上面修饰变量时的性质一样。

#const修饰成员函数:

(1)const修饰的成员函数不能修改任何的成员变量(mutable关键字修饰例外)

(2)const成员函数不能调用非onst成员函数,因为非const成员函数可以会修改成员变量;

1 #include
2 using namespace std;
3 class Point{
4 public :
5 Point(int _x):x(_x){}
6
7 void testConstFunction(int _x) const{
8
9 ///错误,在const成员函数中,不能修改任何类成员变量
10 x=_x;
11
12 ///错误,const成员函数不能调用非onst成员函数,因为非const成员函数可以会修改成员变量
13 modify_x(_x);
14 }
15
16 void modify_x(int _x){
17 x=_x;
18 }
19
20 int x;
21 };
#const修饰成员函数返回类型:

返回形式有两种:

1、返回函数指针:如果返回const data,non-const pointer,返回值也必须赋给const data,non-const pointer。因为指针指向的数据是常量不能修改。

2、返回值的形式:如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。所以,对于值传递来说,加const没有太多意义。

【注意】函数写成const int T(void)和int T(void)等效的;

1 const int * mallocA(){ ///const data,non-const pointer
2 int *a=new int(2);
3 return a;
4 }
5
6 int main()
7 {
8 const int *a = mallocA();
9 ///int *b = mallocA(); ///编译错误
10 return 0;
11 }
3、类中定义static数据成员、static成员函数:

#static数据成员:

    static数据成员独立于该类的任意对象而存在,可以直接通过作用域操作符,通过类直接调用;或者是像一般数据成员一样,通过对象、引用、或指向该类类型对象的指针直接调用(前提是,static数据成员权限必须是public,不能是private);

    如果类中定义多个static数据成员,static数据成员初始化的次序是按照static数据成员在类中的声明次序进行初始化的;

【注意】类中不能给static初始化;如果需要初始化,只能对const int类型初始化,const string等都不行;
例:

class stu
{
public:
static int age;
static const int age=20;
static const string name=“xiaoming” //error
private:

};
函数中通过作用域操作符来初始化:
int Person::age=20;
#static成员函数:
static成员函数同样是类的组成部分并不属于任何对象的组成部分,因此,static成员函数没有this指针。一般而言,类中的成员函数具有一个附加的隐含实参,即指向该类对象的一个指针。这个隐含实参命名为this。因为static成员函数不是任何对象的组成部分,所以static成员函数就没有this形参了。
由于成员函数声明为const说明该成员函数不会修改该成员函数所属的对象,所以static成员函数不能声明为const。为什么呢?因为static成员函数不是任何对象的组成部分。static成员函数可以直接访问所属类的static成员,但是不能直接使用非static成员函数!也不能访问static const 类型的成员!
###Virtual关键词:

虚函数、纯虚函数:实现多态;

虚基类:多重继承,防止包含多个基类对象,造成资源浪费;

1、虚函数:

类Base中加了Virtual关键字的函数就是虚拟函数,在Base的派生类Derived中通过重写虚拟函数来实现对基类虚拟函数的覆盖。当基类Base的指针指向派生类Derived的对象时,实际调用Derived的覆写函数而不是基类的虚函数,这也是面向对象中多态的体现:

总结:基类的对象在调用函数时,如果有virtual则根据多态性调用派生类的覆写函数,如果没有virtual则是正常的静态函数调用,还是调用基类的。

2、纯虚函数:

纯虚函数可以看只是为子类提供一个接口,其本身是不能实例化的;

总结:包含一个或多个纯虚拟函数的类被编译器识别为抽象基类。抽象基类不能被实例化,一般用于继承。

3、虚拟继承:
在多继承下,虚继承就是为了解决菱形继承中,B,C都继承了A,D继承了B,C,那么D关于 A的引用只有一次;
权限:可以采用public、protected、private三种不同的继承关键字进行修饰;
示例:
class A{
void func(){};
};
class B :public virtual A{
void func2(){};
};
虚继承:在继承定义中包含了virtual关键字的继承关系;(继承修饰中存在关键字virtual)
虚基类:在虚继承体系中的通过virtual继承而来的基类,(基类存在virtual修饰的函数)
4、C++三大特性:继承、多态、封装;
继承:
继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码,同时,子类也可以定义自己的属性,或者是重新覆写父类的某些方法和属性,使其获得与父类不同的功能。
多态:
多态是建立在继承的基础上;多态性,允许将子类类型的指针赋值给父类类型的指针,多态性在C++中是通过虚函数实现的。
虚函数就是允许被其子类重新定义的成员函数。而子类重新定义父类虚函数的做法,称为“覆盖”,或者称为“重写”。子类重写父类中虚函数时,即使不用virtual声明,该重载函数也是虚函数。
封装:

封装就是隐藏部分关键成员,而只是让小部分成员作为类与外部的接口,而封装部分只能通过某些特定的方式才能访问。封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是通过外部接口以及特定的访问权限来使用类的成员;
5、进程、线程与协程:
https://www.cnblogs.com/zhang-can/p/7215506.html
#进程:一个程序在一个数据集中的一次动态执行过程,是CPU资源分配和调度的独立单位;可以理解为—正在执行的程序,而数据集表示的是进程执行所需要的资源;注意:进程一般都是由程序、数据集和进程控制块三部分组成;而进程控制块是用来记录下进程外部特征和描述进程的执行变化过程;系统可以通过它管理进程。
进程的局限在于创建、撤销和切换的开销较大,因此引入线程;
父进程与子进程:共享代码段,其他所有资源都是复制父进程的一个副本,当然也就不共享地址空间;从而可以理解成父子进程为互不相干的两个独立进程;文件描述符:子进程通过继承父进程文件描述符,与父进程共享文件描述项,即一个进程改变了文件,另外一个进程也知晓;
#线程
线程,被称为轻量级进程,是一个基本的CPU执行单元,也是程序执行中最小单元;一个进程可以包含多个线程;
线程由线程ID、程序计数器、寄存器集合和栈四部分组成;
优点:线程解决了进程切换开销大的问题,线程在执行中开销相对小很多,提高了操作系统的并发性能;
缺点:线程没有属于自己的系统资源,所能做的很有限,但是同一进程中的多个线程能共享线程资源;
线程间共享进程中所有资源,每个线程只拥有小部分属于自己的资源—栈空间;用于保存运行状态和局部自动变量;
#协程:
协程被称为微线程,和进程、线程操作系统调度不同的是,协程是由用户控制调度的。
协程关键字—yeild,一个子程序入口,通过yield方式转移执行权的协程之间不是调用者与被调用者的关系,而是彼此对称、平等的,通过相互协作共同完成任务。其运行的大致流程如下:
第一步,协程A开始执行。
第二步,协程A执行到一半,进入暂停,通过yield命令将执行权转移到协程B。
第三步,(一段时间后)协程B交还执行权。 第四步,协程A恢复执行。
协程的特点在于是一个线程执行,与多线程相比,其优势体现在:

协程的执行效率非常高。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
协程不需要多线程的锁机制。在协程中控制共享资源不加锁,只需要判断状态就好了。
Tips:利用多核CPU最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。

#进程、线程之间关系:

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程;

(2)资源分配给进程,进程是程序的主体,同一进程的所有线程共享该进程的所有资源;

(3)cpu分配给线程,即真正在cpu上运行的是线程;

(4)线程是最小的执行单元,进程是最小的资源管理单元;

#并行与并发区别:

并行处理是指计算机系统中能同时执行两个或多个任务的计算方法,并行处理可同时工作于同一程序的不同方面

并发处理是同一时间段内有几个程序都在一个cpu中处于运行状态,但任一时刻只有一个程序在cpu上运行。

并发的重点在于有处理多个任务的能力,不一定要同时;而并行的重点在于就是有同时处理多个任务的能力。并行是并发的子集;

在这里插入图片描述这图是借鉴网上的,觉得方便理解的!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值