首页 > 技术文章 > C++知识点总结

liweikuan 2021-05-27 16:56 原文

C++知识点整理总结:

目录

一. C++(I)重点知识:

二. C++(II)重点知识:

 

C++书写标准:

  1. 数据放在private
  2. 参数尽量用引用来传,需不需要const,看情况。
  3. 返回值尽量用引用来传
  4. 在类的本体中,函数应该加const的要加。
  5. 构造函数中的参数初始化列表要尽量用。

 

一.C++(I)重点知识:

 

主要介绍了两种class类型:1)class中不带指针成员   2)class中包含指针成员

 

*包含头文件的两种方法#include<>#include””;

如果是自己写的头文件,使用#include””包含, 如果包含的是C++标准库,使用#include<>来包含。

 

头文件中使用防卫式声明:

 

建议:为了不必要的麻烦,最好在每个头文件上加上这样的防卫式声明。即使现在你只有一个cpp使用该头文件,万一之后再有别的cpp使用该头文件嘞。
PS:防卫式声明一般这样写:__(2个下划线,不是1)+头文件名的大写(不包括.h+__(2个下划线,不是1),例如头文件为head.h时,就使用__HEAD__,这是为了防止重复。

 

 

目录

一. C++(I)重点知识:

1) class中不带指针成员

2) class中包含指针成员

1. Prototype设计模式:

2. 委托+继承关系下的Composite设计模式应用于文件系统开发的原理

3. 委托+继承关系下的observer设计模式的应用和原理

4. 继承+复合关系下的构造与析构函数调用

5. 虚函数和TemplateMethod模式的原理和应用重点

6.复合关系和Adapter模式以及复合关系下的构造和析构函数的讲解

二. C++(II)重点知识:

 

1) class中不带指针成员

 

  1. 关于inline的用法:

Inline用于函数的声明,函数可以被声明为inline类型及内联类型, inline函数提高运行效率(inline只是对编译器的一种建议,简单函数会被inline,复杂函数不一定会被inline),建议将函数inline.

 

class内完成定义的函数,编译器会自动对其进行inline 尝试。

class外完成定义的函数,可以使用inline关键字对其进行inline尝试。

 

 

  2.关于友元函数的使用:

 

 

    

  面向对象三大特性:封装,继承,多态。友元函数可以说是在保持封装性的情况下,提供了其他对象对另一个对象的操作方式(两个对象可以属于同一class,也可以不属于同一个class);同一class的不同对象之间是友元关系。

 

 3.常量const的使用:

  

Const 修饰对象,若函数体内,不会对传入对象进行修改,则函数形参前加const,表示此对象在函数运行过程中不会被改变。

Const修饰函数 即在函数名()之后加const修饰,可以保证函数在之后的运行过程中可以正确运行。可以使用以下例子来说明:

 

 

函数名( )之后加const,意味函数体内不会对成员数据进行任何更改操作。

之后无论是使用complex c1(2,1) 还是 const complex c1(2,1)来创建对象都可以;但是,如果不加const,使用 const complex c1(2,1)创建对象后,cout<<c1.real( )会报错。

 

 

4.关于构造函数的使用:

合理运用初始化列表可以有效提高运行效率。

构造函数的执行过程:先执行初始化列表,后执行函数体的内容。

构造函数重载注意事项:
    

 

 

5.关于运算符重载:

 

1) return by value 还是 return by referrence??

   若在函数内部没有创建临时对象,则尽量使用引用类型对返回值进行接收; 若在函数内部创建临时,则使用value对返回值进行接收.

 使用reference接收的好处:

 

 

2) 临时对象:

再一个函数中,通过调用构造函数生成临时的一个对象,用来存储新生成的数据,当函数执行结束后,临时对象将会被编译器清除,可以通过返回value的方式,将临时对象中的数据返回。

 

 

3) 运算符重载(+,+=,<<)

重载<< ostream& operator<<( ostream& os,const String str ) ,需要将重载函数写成全局函数。

 

2) class中包含指针成员

    1.array New一定要搭配array Delete 使用:

  例如:

    

如图: new String[3]意味创建了包含3string类型对象的数组,在创建过程中会调用3String类型的构造函数; 如果使用delelte  p来释放p指针,则只会调用一次析构函数,释放p所指向的数组空间的第一个string对象, 但是数组空间中其余2string类型对象中包含指针数据,指针数据所指向的内存空间并不会被释放掉,造成内存泄漏; 因此必须使用delelte [] parray New一定要搭配array Delete使用。

 

 2.namespace的使用:

 

      

   

 3.stackheap以及newdelete的使用和原理

      

 

       

 

         

 

  1. static的使用:

     

 

class中的数据成员设置为static类型,或者将函数成员设置为static类型。设置为static的数据成员和函数成员,在内存中单独存在,static函数成员只能处理static数据成员,static函数中不包含this指针。

 

调用static函数的方式:

(1)通过object调用

(2)通过class name调用

 

 

 1.单例模式:singleton)

单例模式:确保一个类只有一个实例,并提供一个全局访问点。

例子:构造函数放在private域中

 

 在此例子中只需要一个A的对象,可以使用单例模式来完成。

 

      

此例子中:

A的构造函数写在了private中,成员函数getinstance()用来创建一个A的静态对象a,并返回a对象的引用。

 

应用:单例模式可以用来做初始化数据库的连接操作,线程池,缓存,日志对象,显卡等设备的驱动程序。

 

 

 

 

 

经典的单例模式实现(java)(延迟实例化):                                

      Public class Singleton{                                                                                                                              

                Private  static  Singleton  uniqueInstance;                                                                                 

                //这里是其他的有用实例化变量                      

                Private   Singleton( ) { }      //私有的构造函数                      

                Public  static  Singleton  getInstance( )                

                      {                                          

                           If(uniqueInstance == null)                       

                            {                                    

                               uniqueInstance= new Singleton( );       

                             }                                    

                         Return  uniqueInstance;                       

                       }                                              

                  //这里是其他的有用方法                                 

            }                                                          

 

 

以上情况注意***在使用单例模式时,需要考虑多线程并发导致生成多个实例的情况。

 

处理多线程的方法:

1.将getInstance()变成同步(synchronized)方法, 若此段程序使用频繁,此方法会造成程序效率的大幅下降。

     经典的单例模式实现(java)(延迟实例化):                            

      Public class Singleton{                                            

                Private  static  Singleton  uniqueInstance;             

                //这里是其他的有用实例化变量                             

                Private   Singleton( ) { }      //私有的构造函数              

                Public  static  synchronized  Singleton  getInstance( )         

                      {                                                  

                           If(uniqueInstance == null)                        

                            {                                        

                               uniqueInstance= new Singleton( );           

                             }                                           

                         return  uniqueInstance;                            

                       }                                                

                  //这里是其他的有用方法                              

            }                                 

 

2.使用双重检查加锁”,在getInstance()中减少使用同步。保证程序的性能。(最佳方法)

 

Public class Singleton{                                            

                Private  Volatile  static  Singleton  uniqueInstance;             

                //这里是其他的有用实例化变量                             

                Private   Singleton( ) { }      //私有的构造函数              

                Public  static  Singleton  getInstance( )                 

                  {                                                   

                      If(uniqueInstance == null)                        

                      {                                           

                          synchronized (Singleton.class)                   

                           {                                          

                             If(uniqueInstance == null)                        

                              {                                        

                               uniqueInstance= new Singleton( );           

                               }                                       

                           }                                        

                       }                                                

                         return  uniqueInstance;                            

                       }                                                

                  //这里是其他的有用方法                              

            }            

 

 

 

使用急切创建实例,而不是使用延迟实例化的做法

 

经典的单例模式实现(java)(急切实例化):                                           

         Public class Singleton{                                                            

                Private  static  Singleton  uniqueInstance = new Singleton( );                                

                //这里是其他的有用实例化变量                                         

                Private   Singleton( ) { }      //私有的构造函数                              

                Public  static  Singleton  getInstance( )                                  

                      {                                                                                                                

                         return  uniqueInstance;                                      

                       }                                                            

                  //这里是其他的有用方法                                            

            }                                                           

 

 

 

 

 

 

 

 

  1. cout函数的原理说明:

 

 

 

 

 

 

 

  1. 模板和函数模板:

     

 

 

     

 

 

  1. 浅拷贝和深拷贝:

 

class中包含指针数据成员,需要定义一下三种函数:

 

BIG Three函数:1.拷贝构造函数   2.拷贝赋值函数  3.析构函数

 

 

浅拷贝:

c++中,提供的对象之间的赋值是浅拷贝,例如:a=b; 将对象b赋值给对象a, 只是将ab对象中的指针指向同一地址,这样会造成内存泄露;同时也会带来不确定性的危险,例如:在后续操作中,改变ab中的某一指针所指地址中的数据,相当于ab同时改变。

 

深拷贝:

通过拷贝构造函数不改变ab对象中指针的地址,而将所指地址中的数据改为相同。

深拷贝两种方法:

1.拷贝构造函数:利用构造函数来进行对象的拷贝,例如:

                      String  s1("Hello");

                      String  s2(s1);  //调用所属class的拷贝构造函数

 

 

2.拷贝赋值函数:利用运算符重载来进行对象的拷贝(赋值),  例如:

                           String s1("Hello");

                           String s2;

                           s2 = s1;   // 调用classoperator成员函数

 

3.析构函数:在对象的生命周期结束时,被调用,用来将对象中的指针所指地址进行释放。

 

 

9.参数传递:pass by value vs pass by reference(to const)

 

   

 

1.使用value传递,可能因为数据的大小影响运行效率。例如:char数据是1个字节,指针是4个字节,”引用”本质上是指针的封装,但是速度比指针更快。

  2.使用引用传递,速度更快,并且和指针传递效果一样,在函数内对可以对引用的数据进行修改。

  3.上图中,complex& operator += (const  complex&);   其中const表明:通过引用传递到函数体内的数据不能在函数体内进行修改。

 

 

返回值类型尽量使用引用。

 

 

 

 

面向对象编程重中之重(继承、复合、委托)

 

复合关系:及在一个类的数据成员中包含包含其他类的对象。

 

继承关系:及子类继承父类

 

委托关系:及在一个类的数据成员中包含包含其他类的指针。

 

 

  1. Prototype设计模式:

 

      

 

 

 

 

 

 

  1. 委托+继承关系下的Composite设计模式应用于文件系统开发的原理

 

 

 

     

 

 

 

 

  1. 委托+继承关系下的observer设计模式的应用和原理

 

        

 

 

 

 

  1. 继承+复合关系下的构造与析构函数调用

 

        

 

 

  1. 虚函数和TemplateMethod模式的原理和应用重点

 

     

 

     

 

 

6.复合关系和Adapter模式以及复合关系下的构造和析构函数的讲解

 

      

 

       

 

   复合关系下,构造函数是先调用内部复合的构造函数,然后再执行自己的构造函数。析构函数是先执行自己的析构函数,再执行内部复合的析构函数。

 

 

 

 

二.C++(II)重点知识:

 

  1. 转换函数conversion function

 

             

 

 

 

 

  1. Pointer-like-class智能指针

 

                      

 

Pointer-like-class智能指针:   就是像指针的class, 该类所创建的对象,拥有普通指针所拥有的功能,此外还可以根据自己的需要对其进行扩展。

 

 

 

  1. pointer-like-class智能指针-迭代器

    

 

    

 

 

  1. function-like-class仿函数

 

    

 

 

 

 

 

  1. class template 和 function template 和 menber template

 

 

        

 

 

     

 

 

         

 

 

  1. 模板特化和模板偏特化

          

 

     

 

 

 

 

  1. 模板模板参数

 

                       

 

 

  1. reference的本质原理理解(重点)

 

 

 

 

 

 

9.复合继承关系下的构造和析构

 

 

   复合关系下,构造函数是先调用内部复合的构造函数,然后再执行自己的构造函数。析构函数是先执行自己的析构函数,再执行内部复合的析构函数。

 

 

 

 

 

10.多态与虚函数与虚机制与虚指针的本质理解和关系

 

 

如果一个类中包含虚函数,则再内存分配中,会为该类的对象分配一个虚指针vptr,不论class中有多少个虚函数,对象中都只有一个虚指针;  虚指针指向虚表vtbl虚表中存有对象所包含虚函数的地址;  虚机制:就是对象在调用虚函数的过程中,通过虚指针找到虚表,通过虚表中虚函数的地址找到相应的虚函数,进行调用的过程。  多态是靠虚机制来进行表现。

 

 

 

 

 

 

 

 

 

 

  1. 关于this指针的理解:

 

   当对象调用所属类的函数成员时,会隐式的将对象的地址传入函数中,this就是指向这个对象的指针。

 

 

 

 

 

  1. 关于动态绑定的理解:

 

动态绑定是与虚机制有关的,

 

 

 

  1. 关于new, delete,  operatorNew和operatorDelete的重载(难)可用来做内存池

 

 

 

 

 

 

 

 

 

 

 

 

 

   装饰者模式(组合composition+委托delegation):  

 

适用于的情景: 利用继承无法完全解决问题,类数量爆炸、设计死板,以及基类加入的新功能并不适用于所有的子类。

 

目标是:允许类容易扩展,在不修改现有代码的情况下,就可以搭配新的行为,及(对扩展开放,对修改关闭)

 

注意:在选择需要被扩展的代码部分时要小心。每个地方都采用开放-关闭原则,是一种浪费,也没必要,还会导致代码变得复杂且难以理解。

 

 

 

 

 

观察者模式

推荐阅读