刷牛客网的知识点整理-C++【持续更新...】

来源:互联网 发布:java ireport 打印 编辑:程序博客网 时间:2024/06/06 11:36
  1. 对于内置类型而言,new仅仅是分配内存,除非后面显示加(),相当于调用它的构造函数,对于自定义类型而言,只要一调用new,那么编译器不仅仅给它分配内存,还调用它的默认构造函数初始化,即使后面没有加()
  2. _beginthreadex()比较于 CreateThread()有更高的线程安全性,不会造成多个线程共用同一个全局变量的情况
  3. 自增运算符的优先级比取址运算符优先级高
  4. 基类的公有成员在派生类中权限由派生规则决定
  5. 普通成员函数不算到字节里面,虚函数有一个指向虚函数列表的指针,无论有多少个虚函数都是占用一个字节的大小。
  6. 初始化指针时所创建的字符串常量被定义为只读。如果试图通过指针修改这个字符串的值,程序就会出现未定义的行为
  7. free指的是释放该指针所指向的内存资源,指针值没有变化,为了防止指针成为野指针,需要在free后将指针置为NULL
  8. o% 表示8进制进行输出,数字前加0表示八进制数,加0x表示16进制。
  9. 在派生类中重新定义该虚函数时,关键字virtual可以写也可以不写。
  10. 一个虚函数无论被公有继承多少次,它仍然保持其虚函数的特性。
  11. 虚函数必须是其所在类的成员函数,而不能是友元函数,也不能是静态成员函数(static
  12.  std::sort 不是稳定的排序算法,它不保证相等元素的相对位置,使用 std::stable_sort 来保证这一点
  13. 一:序列容器, 有vector, list, deque, string.

 : 关联容器,     set, multiset, map, mulmap, hash_set, hash_map, hash_multiset, hash_multimap

其他的杂项: stack, queue, valarray, bitset

  1. x86是小端存储,x64是大端存储
  2. dynamic_cast<>用于C++类继承多态间的转换,分为:
    1.
    子类向基类的向上转型(Up Cast)
    2.
    基类向子类的向下转型(Down Cast)
    其中向上转型不需要借助任何特殊的方法,只需用将子类的指针或引用赋给基类的指针或引用即可,dynamic_cast向上转型其总是肯定成功的。

 

而向下转换时要特别注意:dynamic_cast操作符,将基类类型的指针或引用安全的转换为派生类的指针或引用。dynamic_cast将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理。这也是dynamic_cast与其他转换不同的地方,dynamic_cast涉及运行时类别检查,如果绑定到引用或指针的对象不是目标类型的对象,则dynamic_cast失败。如果是指针类型失败,则dynamic_cast的返回结果为0,如果是引用类型的失败,则抛出一个bad_cast错误。
注意:dynamic_cast在将父类cast到子类时,父类必须要有虚函数。因为dynamic_cast运行时需要检查RTTI信息。只有带虚函数的类运行时才会检查RTTI

 

  1. *p要考虑这是指针还是数组,分开讨论
  2. BSSBlock Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。特点是:可读写的,在程序执行之前BSS段会自动清0。所以,未初始的全局变量在程序执行之前已经成0了。

    数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。

    代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

    堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

    (stack):栈又称堆栈,是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区
  3. 并不是所有的操作符都能被重载。除了 .  .*  ::  ? :  sizeof  typeid 这几个运算符不能被重载,其他运算符都能被重载。
  4. 1. &a+i = a + i*sizeof(a); 

2. a+i = a +i*sizeof(a[0]);  

  1. 静态分配是指在编译阶段就能确定大小,由编译器进行分配,堆不可以进行静态分配,堆的申请都是在执行过程中进行的。

A,堆和栈的大小都可以设置,栈一般只有几KB

B,堆在动态分配时,要申请连续的内存空间,释放后会产生碎片。

D,堆是使用malloc()calloc()realloc()等函数动态分配的,而使用alloca()函数可以动态分配栈的内存空间,释放的时候由编译器自己释放

  1. STL中的常用容器包括:顺序性容器(vectordequelist)、关联容器(mapset)、容器适配器(queuestac
  2. memcpymemmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。

但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销

  1. 构造函数初始化时必须采用初始化列表一共有三种情况,   
    1.
    需要初始化的数据成员是对象(继承时调用基类构造函数)   
    2.
    需要初始化const修饰的类成员   
    3.
    需要初始化引用成员数据
  2. 指针指向常量(如char*str=“aaaaa”)和NULL时,不能通过指针修改常量,因为常量本身就是只读的。
  3. 首先所谓的接口是指只包含纯虚函数的抽象类,和普通的抽象类含不一样。接口必须是纯虚函数。接口是特殊的抽象类,抽象类的唯一左右就是创建派生类,不能定义抽象类的对象,所以C是正确的。接口即只包含纯虚函数的抽象类。一个类可以实现多个接口。
  4. 模板属于编译时多态,编译时根据模板生成模板函数。
  5. 编程语言中的 malloc  calloc 函数和 C++  new 运算符都是在动态存储区( heap )上申请内存空间
  6. 1  结构体的大小等于结构体内最大成员大小的整数倍
    2
      结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,比如说double型成员相对于结构体的首地址的地址偏移量应该是8的倍数。
    3
      为了满足规则12编译器会在结构体成员之后进行字节填充!

  7. 这个"常量折叠"就是在编译器进行语法分析的时候,将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。可以算作一种编译优化。

因为编译器在优化的过程中,会把碰见的const全部以内容替换掉(跟宏似的: #define pi 3.1415,用到pi时就用3.1415代替),这个出现在预编译阶段;但是在运行阶段,它的内存里存的东西确实改变了!!!

简单的说就是,当编译器处理const的时候,编译器会将其变成一个立即数。 

  1. 模板类的好处:(1)可用来创建动态增长和减小的数据结构2)它是类型无关的,因此具有很高的可复用性。3)它在编译时而不是运行时检查数据类型,保证了类型安全4)它是平台无关的,可移植性5)可用于基本数据类型
  2. o% 表示8进制进行输出
  3. 在用作定义时char[0]是空数组,是不占空间的。
  4. memcpymemmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。
  5. 静态分配是指在编译阶段就能确定大小,由编译器进行分配,堆不可以进行静态分配,堆的申请都是在执行过程中进行的。
  6. c11 新增 array forward_list unordered4个关联容器
  7. C++对空类或者空结构体 ,对其sizeof操作时候,默认都是 1个字节
  8. 对于内置类型而言,new仅仅是分配内存,除非后面显示加(),相当于调用它的构造函数,对于自定义类型而言,只要一调用new,那么编译器不仅仅给它分配内存,还调用它的默认构造函数初始化,即使后面没有加()
  9. _beginthreadex()比较于 CreateThread()有更高的线程安全性,不会造成多个线程共用同一个全局变量的情况
  10. 静态成员属于类,而不是属于某个特定的对象,它是由该类的所有对象共享的,因此不能在类的构造方法中初始化
    静态成员属于该类所有对象公有,可以被类对象调用
    静态成员收private的限制
    静态成员属于类和该类的所有对象,可以用类名直接调用
  11. 调用拷贝构造函数的3中情况:

1、用一个对象去初始化同一个类的另一个新对象时

2、函数的形参对象,调用函数进行形参和实参结合时

3、函数的返回值是类的对象,函数执行返回调用时将一个对象赋值给另一个对象,两个对象都存在,调用的是赋值构造函数,不涉及内存的分配。

当被赋值的对象不存在调用的是拷贝构造函数。

  1. 因为++--有前缀和后缀两种形式,为了区分,要求在后缀形式加一个int参数。  const Fraction operator ++(int)    int不过是个哑元(dummy,是永远用不上的,它只是用来判断++是prefix  还是  postfix  。如果有哑元,则是postfix,否则,就是prefix 
  2. %x是按16进制输出
  3.  在继承中派生类的对象调用构造函数的顺序,应该是先调用基类的构造函数,然后是成员中的对象对应类的构造函数,最后是派生类自己的构造函数.
  4. 重载:

    只有在 同一类定义中的同名成员函数才存在重载关系 ,主要特点是 函数的参数类型和数目有所不同 ,但 不能出现函数参数的个数和类型均相同 ,仅仅依靠返回值类型不同来区分的函数,这和普通函数的重载是完全一致的。另外,重载和成员函数是否是虚函数无关

覆盖:

    在派生类中覆盖基类中的同名函数,要求两个函数的参数个数、参数类型、返回类型都相同,且基类函数必须是虚函数。

隐藏:  

派生类中的函数屏蔽了基类中的同名函数,

2个函数参数相同,但基类函数不是虚函数(和覆盖的区别在于基类函数是否是虚函数)。2个函数参数不同,无论基类函数是否是虚函数,基类函数都会被屏蔽(和重载的区别在于两个函数不在同一类中)

  1. C语言中:||为逻辑或,只要有一个为真,即为逻辑真 1

                 |位按位或,化成二进制进行或运算。5|7=0101|0111=0111=7

  1. 一维数组:

    a <=> &a[0]        a+1 <=> &a[1]

    *a <=> a[0]         *(a+1) <=> a[1]

二维数组:

     a[0] <=>&a[0][0]    a[1] <=> &a[1][0]      a[1]+1 <=> &a[1][1]

    *a[0] <=>a[0][0]     *a[1] <=> a[1][0]       *(a[1]+1 ) <=> a[1][1]

  1.  Vector  iterator  listIterator 方法所返回的迭代器是快速失败的 :如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的 remove  add 方法之外的任何其他方式),则迭代器将抛出 ConcurrentModificationException
  2. 回调函数就是一个通过函数指针调用的函数。

       如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

       回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

  1. 不能声明为虚函数的有:

1.普通函数(不能被覆盖) 

2.友元函数(C++不支持友元函数继承)

3.内联函数(编译期间展开,虚函数是在运行期间绑定)

4.构造函数(没有对象不能使用构造函数,先有构造函数后有虚函数,虚函数是对对象的动作) 

5.静态成员函数(只有一份大家共享)

  1. 进程是指一个具有一定独立功能的程序关于某个数据集合的一次运动活动。简单地说进程是可以并发执行的程序的执行过程,它是控制程序管理下的基本的多道程序单位。

进程控制块(PCB )是由系统为每个进程分别建立的,用以记录对应进程的程序和数据的存储情况,记录进程的动态信息。PCB是一个进程存在的标志。

一个进程可以有多个进程控制块,不可和其他进程共用一个进程控制块。

  1. 编译:进行语法检查、函数分配空间,将各个函数编译成二进制码,按照特定目标文件格式生成目标文件。

连接:把程序中各个文件编译生成的目标文件连接起来,同时还要同系统提供的资源(如函数库)连接成为一个整体,得到可执行文件。

运行:执行连接好的程序。

重定位:把程序的逻辑地址空间变换成内存中的实际物理地址空间的过程,也就是说在装入时对目标程序中指令和数据的修改过程。

  1. 实现链接的方式有三种(链接时间不同):

1.静态链接

2.动态链接(装入时)

3.动态链接(运行时)

  1. A类地址A类地址1字节为网络地址,其它3个字节为主机地址。另外第1个字节的最高位固定为0

  A类地址范围:1.0.0.1126.255.255.254

   A类地址中的私有地址和保留地址:

  10.0.0.010.255.255.255私有地址(所谓的私有地址就是在互联网上不使用,而被用在局域网络中的地址)。

  127.0.0.0127.255.255.255是保留地址,用做循环测试用的。

  2. B类地址B类地址1字节和第2字节为网络地址,其它2个字节为主机地址。另外第1个字节的前两位固定为10

  B类地址范围:128.0.0.1191.255.255.254

   B类地址的私有地址和保留地址

   172.16.0.0172.31.255.255是私有地址

  169.254.0.0169.254.255.255是保留地址。如果你的IP地址是自动获取IP地址,而你在网络上又没有找到可用的DHCP服务器,这时你将会从169.254.0.0169.254.255.255中临得获得一个IP地址。

  3. C类地址C类地址1字节、第2字节和第3个字节为网络地址,第4个个字节为主机地址。另外第1个字节的前三位固定为110

  C类地址范围:192.0.0.1223.255.255.254

   C类地址中的私有地址:192.168.0.0192.168.255.255是私有地址。

  1. FTP使用TCP的服务,有两个特定的端口,端口20用于控制连接。端口21用于数据连接
  2. crontab 分六大块组成,具体如下:  MIN(分钟) HOUR(小时) DAY(日期) MONTH(月份) DAYOFWEEK(星期) COMMAND(命令)
  3. Aip协议是网络层协议,提供ip路由功能

BICMP是(Internet Control Message ProtocolInternet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。

CARP协议是地址解析协议,用于将ip地址转换为对应的mac地址

DRARP是逆地址解析协议,跟ARP相反,用于将Mac地址转换为ip地址

  1. 有关tcp连接握手

1. accept() api调用发生在三次握手之后

2. “三次握手的目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误

3. 因为tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据,所以断开连接时必须是四次握手

  1. 每一层的协议如下:

物理层: RJ45  CLOCK  IEEE802.3     (中继器,集线器,网关)

数据链路: PPP  FR  HDLC  VLAN  MAC   (网桥,交换机)

网络层: IP  ICMP  ARP  RARP  OSPF  IPX  RIP  IGRP  (路由器)

传输层: TCP  UDP  SPX

会话层: NFS  SQL  NETBIOS  RPC

表示层: JPEG  MPEG  ASII

应用层: FTP  DNS  Telnet  SMTP  HTTP  WWW  NFS

  1. malloc申请的是虚拟内存,而不是物理内存。

1) malloc 函数: void *malloc(unsigned int size)

     在内存的动态分配区域中分配一个长度为size的连续空间,如果分配成功,则返回所分配内存空间的首地址,否则返回NULL,申请的内存不会进行初始化。

2calloc 函数: void *calloc(unsigned int num, unsigned int size)

     按照所给的数据个数和数据类型所占字节数,分配一个 num * size 连续的空间。

    calloc申请内存空间后,会自动初始化内存空间为 0,但是malloc不会进行初始化,其内存空间存储的是一些随机数据。 
3
realloc 函数: void *realloc(void *ptr, unsigned int size)

    动态分配一个长度为size的内存空间,并把内存空间的首地址赋值给ptr,把ptr内存空间调整为size

    申请的内存空间不会进行初始化。
4
new是动态分配内存的运算符,自动计算需要分配的空间,在分配类类型的内存空间时,同时调用类的构造函数,对内存空间进行初始化,即完成类的初始化工作。动态分配内置类型是否自动初始化取决于变量定义的位置,在函数体外定义的变量都初始化为0,在函数体内定义的内置类型变量都不进行初始化。

  1. ceil 天花板” floor  “地板” ,一个靠上取值,另一个靠下取值,如同天花板,地板。 
  2. ifndef/define/endif 的含义:如果未定义 / 那么定义 / 完成假设

一般是用来防止头文件被重复包含,提高编译效率的。

  1. feof(),如果到达文件末尾则返回非零值,如果没有到达文件末尾,则返回0值。
  2. C语言: char a = 'a'; sizeof(char) = 1 sizeof(a) = 1 sizeof('a') = 4 

C++语言: char a = 'a'; sizeof(char) = 1 sizeof(a) = 1 sizeof('a') = 1 

字符型变量是1字节这个没错,奇怪就奇怪在C语言认为'a'4字节,而C++语言认为'a'1字节。     

原因如下:  

  C99标准的规定,'a'叫做整型字符常量(integer    character constant),被看成是int型,所以在32位机器上占4字节。

  ISO C++标准规定,'a'叫做字符字面量(character literal),被看成是char型,所以占1字节

  1. (heap)
  2. 1、当你给WEB服务器接上网线的时候,它会自动发送一条ARP信息,使得接入网关能找的到它;网关上会形成一条类似:2c 96 1e 3c 3e 9b - 192.168.1.123MAC地址到IP地址的映射记录。

2、如用户在浏览器中输入域名,如本地DNS缓存中没有,必然会进行一次DNS查询,以确定该域名的IP地址。

3HTTP。获得DNS对应的IP地址以后,使用HTTP协议访问web服务器(不考虑TCP三次握手建立连接的阶段)。

         ARP -> DNS -> HTTP

  1. Linux用户分为:拥有者、组群(Group)、其他(other

linux中的文件属性过分四段,如  -rwzrwz---

第一段  -  是指文件类型表示这是个普通文件

文件类型部分

-为:表示文件

d为:表示文件夹

l为:表示链接文件,可以理解为 windows中的快捷方式(link file

b为:表示里面可以供存储周边设备

c为:表示里面为一次性读取装置

 

第二段  rwz  是指拥有者具有可读可写可执行的权限  

类似于windows中的所有者权限比如 administrator 对文件具有修改、读取和执行权限

 

第三段  rwz 是指所属于这个组的成员对于这个文件具有,可读可写可执行的权限      

类似于windows中的组权限比如administrators组,属于这个组的成员对于文件的都有可读可写可执行权限

 

第四段  --- 是指其他人对于这个文件没有任何权限

类似于windows中的 anyone 一样就是说所有人对着个文件都会有一个怎样的权限

  1. Linux系统中哪个文件你可以存储用于创建用户目录的系统用户默认文件? /etc/skel
  2. Nagle算法主要是用来避免大量的小数据包在网络中传输,从而降低网络容量利用率。比如一个20字节的TCP首部+20字节的IP首部+1个字节的数据组成的TCP数据报,有效传输通道利用率只有将近1/40。如果网络充斥着这样的小分组数据,则网络资源的利用率是相当低下的。—— 但是对于一些需要小包场景的程序,比如像telnetssh这样的交互性比较强的程序,你需要关闭这个算法。可以在Socket设置TCP_NODELAY选项来关闭这个算法。
  3. 格式:sync  强制将内存中的文件缓冲内容写到磁盘。
  4.     unordered_map:是所谓的哈希map,很容易就选了hashtable 
             priority_queue:是所谓的优先级队列,说白了就是一个二叉堆,所以底层应该是用heap实现,并非名字中的queue
  1. spooling技术是一种把独占设备改造成逻辑上共享的设备。
  2. IO重定向 是指将命令的执行结果重新导出到其他的设备或者文件。主要包括输入重定向和输出重定向。
  3. 单精度浮点数的有效位数是7位。
    双精度浮点数的有效位数是16位。
  4. fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
    fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值: 
        1)在父进程中,fork返回新创建子进程的进程ID;
        2)在子进程中,fork返回0;
        3)如果出现错误,fork返回一个负值;
  5. classpacket{
         intsize;
         voiddata[0];
    }
    1.这个叫柔性数组,它的作用跟指针差不多,但是指针占空间,而它不占空间,这就意味着可以节省空间。
    2.该数组的内存地址就和它后面的元素地址相同,意味着无需初始化,数组名就是后面元素的地址,直接就能当指针使用。例如,制作动态buffer,可以这样分配空间malloc(sizeof(structXXX) + buff_len); 直接就把buffer的结构体和缓冲区一块分配了。这样使用释放一次即可,如果使用指针,则需要释放两次。
    3.也可以写成data[1]或data[],是考虑到可移植性的原因,因为有些编译器不支持0数组。
  6. 死代码的含义是指永远不会被执行到的代码段,而不是直接抛弃被注释的代码
  7. 在两个线程属于同一个进程的情况下,栈是相互可见的
  8. 因为++和--有前缀和后缀两种形式,为了区分,要求在后缀形式加一个int参数。  const Fraction operator ++(int)   中 int不过是个哑元(dummy),是永远用不上的,它只是用来判断++是prefix  还是  postfix  。如果有哑元,则是postfix,否则,就是prefix 。 
  9. A,静态成员属于类,而不是属于某个特定的对象,它是由该类的所有对象共享的,因此不能在类的构造方法中初始化
    B,静态成员属于该类所有对象公有,可以被类对象调用
    C,静态成员收private的限制
    D,静态成员属于类和该类的所有对象,可以用类名直接调用
  10. a.成员函数被重载的特征:

    (1)相同的范围(在同一个类中);

    (2)函数名字相同;

    (3)参数不同;

    (4)virtual 关键字可有可无。

    b.覆盖是指派生类函数覆盖基类函数,特征是:

    (1)不同的范围(分别位于派生类与基类);

    (2)函数名字相同;

    (3)参数相同;

    (4)基类函数必须有virtual 关键字。

    c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

    (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

    (2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

  11. 使用运算符对数据进行格式输出时,必须要包含iomanip.h头文件。
  12. I/O中断方式是以字节为单位,DMA控制方式是以一个连续的数据块为单位,I/O通道控制方式是DMA控制方式的发展,是以一组数据块为单位的,即可以连续读取多个数据块。
  13. HTTP 不是安全的,HTTPS才是安全的。
  14. Linux进程间通信:管道、信号、消息队列、共享内存、信号量、套接字(socket)
    Linux线程间通信:互斥量(mutex),信号量,条件变量
    Windows进程间通信:管道、消息队列、共享内存、信号量 (semaphore) 、套接字(socket)
    Windows线程间通信:互斥量(mutex),信号量(semaphore)、临界区(critical section)、事件(event)
  15. X.25是数据终端设备DTE通过数据电路端设备DCE进入公共数据交换网PDN所必须遵循的接口规范
  16. 银行家算法是避免死锁
    在资源的动态分配过程中,防止系统进入不安全状态,可避免发生死锁。
  17. 静态数据成员既可以在类体内定义,也可以在类体外定义,但是必须在类体外初始化。
  18. Maxfd是三个套接字描述符中最大数字加上1(采用多路复用I/O监听多个套接字的数据时)
  19. 调用yield方法,让同优先级或比自己优先级高的在就绪状态的线程执行。
  20. 构造函数初始化时必须采用初始化列表一共有三种情况,
    1.需要初始化的数据成员是对象(继承时调用基类构造函数)
    2.需要初始化const修饰的类成员
    3.需要初始化引用成员数据
  21. final修饰的方法不能被覆盖
    final修饰的字段为常量
    final修饰的类不能被继承
  22. 重载多态和强制多态是 指特定多态。
    参数多态和包含多态是指通用多态。
  23. 面向对象的五大基本原则

    单一职责原则(SRP)
    开放封闭原则(OCP) 
    里氏替换原则(LSP) 
    依赖倒置原则(DIP) 
    接口隔离原则(ISP)

  24. 静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员函数不能访问非静态的成员
  25. a.成员函数被重载的特征:

    (1)相同的范围(在同一个类中);

    (2)函数名字相同;

    (3)参数不同;

    (4)virtual 关键字可有可无。

    b.覆盖是指派生类函数覆盖基类函数,特征是:

    (1)不同的范围(分别位于派生类与基类);

    (2)函数名字相同;

    (3)参数相同;

    (4)基类函数必须有virtual 关键字。

    c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

    (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

    (2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)



     

     

     

     

     

     

     

     

     

     

     

    0 0