c++笔记

  1. c++域:局部域、全局域、命名空间域、类域(后两个域不影响生命周期)。Namespace只能定义在全局,且可以嵌套定义。同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
  2. 命名空间展开:using   using namespace yy;(全部展开)   using namespace yy::a(部分展开),展开后,可在局部空间直接使用。
  3. 默认参数:默认参数从右往左给,传参时从左往右传。(从左到右一一对应),默认参数只能在函数声明的时候使用。
  4. 引用:1、引用类型必须和引用实体是同种类型的  1. 引用在定义时必须初始化 2. 一个变量可以有多个引用 3. 引用一旦引用一个实体,再不能引用其他实体
  1. 隐式类型转换时,会生成一个中间变量,有常量属性,所以要用常引用。表达式作为引用主体,也具有常属性,需要常引用

const int a = 10;  

  //int& ra = a;   // 该语句编译时会出错,a为常量  

 const int& ra = a;    

 double d = 12.34;  

 //int& rd = d; // 该语句编译时会出错,类型不同

const int& rd = d;

  1. 如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用 引用返回,如果已经还给系统了,则必须使用传值返回。
  2. 引用和指针的不同点: 1. 引用概念上定义一个变量的别名,指针存储一个变量地址。      2. 引用在定义时必须初始化,指针没有要求 3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何 一个同类型实体 4. 没有NULL引用,但有NULL指针 5. sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32 位平台下占4个字节) 6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小 7. 有多级指针,但是没有多级引用 8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  3. 注意:引用和指针在汇编指令层面上完全一致。
  4. 内联函数:inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销用函数体替换函数调用),内联函数提升程序运行的效率。
  1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会 用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运 行效率。 2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建 议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不 是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。
  2. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址 了,链接就会找不到。
  1. 在c++中,尽量使用nullptr来表示空指针,它可以接受任意类型的指针,但不接受整形。
  2. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。 注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为 是默认构造函数。即,不用传参的构造函数是默认构造函数。
  3. 编译器默认生成的构造函数会对内置成员函数初始化为随机值(视编译器而定),注意:C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在 类中声明时可以给默认值
  4. 析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由 编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作
  1. 析构函数名是在类名前加上字符 ~ 2. 无参数无返回值类型。 3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构 函数不能重载 4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。5.内置成员变量不需要析构,在程序运行结束后,将自动销毁。 6.如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如 Date类;有资源申请时,一定析构,否则会造成资源泄漏,比如Stack类。

          11。拷贝构造函数// Date(const Date& d)   // 正确写法

  1. 拷贝构造函数是构造函数的一个重载形式 
  2. 拷贝构造函数的参数一个必须是类类型对象的引用其他的必须是带缺省值的参数。使用传值方式编译器直接报错, 因为会引发无穷递归调用。c++规定传值传参和传值返回时,会调用一次拷贝构造函数)
  3. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按 字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定 义类型是调用其拷贝构造函数完成拷贝的。
  4. 注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请 时,则拷贝构造函数是一定要写的,否则就是浅拷贝。
  1. 赋值运算符重载
  1. 赋值运算符重载格式

参数类型const T&,传递引用可以提高传参效率

返回值类型T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值    检测是否自己给自己赋值

返回*this :要复合连续赋值的含义this指向的对象函数结束后不会销毁,故以引用方式返回提高效率

            例如:Date& operator=(const Date& d) (第一个参数是隐式的this)

{     

     If(this != &d)

{

   _year=d._year;

}

Return *this;

}

  1. 赋值运算符只能重载成类的成员函数不能重载成全局函数
  2. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。注 意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符 重载完成赋值。
  1. 前置++和后置++重载
  1. 代码对比:

  前置(先++后使用)

   Date& operator++() 在类内实现,默认传递一个this)

{

 _day += 1;

return *this;

}

                    后置(先使用后++)

                  Date operator++(int)

{

Date temp(*this);

    _day += 1;

 return temp;

 }

注意:前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载  C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器 自动传递 // 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存 一份,然后给this+1 //       temp是临时对象,因此只能以值的方式返回,不能返回引用

  1. 初始化列表
  1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
  2. 类中包含以下成员,必须放在初始化列表位置进行初始化: 引用成员变量 const成员变量 自定义类型成员(且该类没有默认构造函数时)
  3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量, 一定会先使用初始化列表初始化。
  4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后 次序无关
  1. static成员

        声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用 static修饰成员函数,称之为静态成员函数静态成员变量一定要在类外进行初始化

       2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明 3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问 4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员 5. 静态成员也是类的成员,受publicprotectedprivate 访问限定符的限制

16.友元

  友元函数可访问类的私有和保护成员,但不是类的成员函数 友元函数不能用const修饰 友元函数可以在类定义的任何地方声明,不受类访问限定符限制 一个函数可以是多个类的友元函数 友元函数的调用与普通函数的调用原理相同

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

友元关系是单向的,不具有交换性不具有传递性。

友元关系不能继承

17.内存管理

1.newdelete是用户进行动态内存申请和释放的操作符operator new operator delete是 系统提供的全局函数new在底层调用operator new全局函数来申请空间,delete在底层通过 operator delete全局函数来释放空间。

2.实现原理

    内置类型:

      如果申请的是内置类型的空间,newmallocdeletefree基本类似,不同的地方是: new/delete申请和释放的是单个元素的空间,new[]delete[]申请的是连续空间,而且new在申 请空间失败时会抛异常,malloc会返回NULL

  自定义类型:

     new的原理 1. 调用operator new函数申请空间底层还是malloc)

 2. 在申请的空间上执行构造函数,完成对象的构造

delete的原理 1. 在空间上执行析构函数,完成对象中资源的清理工作

  1. 调用operator delete函数释放对象的空间

 new T[N]的原理

  1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对 象空间的申请
  2.  在申请的空间上执行N次构造函数

delete[]的原理

  1. 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
  2.  调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释 放空间
  3. 对于内置类型,new[],使用delete 可以,不会内存泄漏,但不建议,对于自定义类型,必须使用delete[],否则会程序崩溃。
  4. New[n]会额外申请4个字节,用来存储n这个整型值,告诉编译器需要执行n次构造函数与析构函数。

18.模板

   1.格式:template<typename T1, typename T2,......typename Tn>  T为类型

   2.函数模板实例化:用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。

         template<typename T>

              T Add(const T& i, cosnt T& j)

                  { return i+j;}

              Int main()

{  int a=10;

   Double b=20;

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值