C++学习笔记

来源:互联网 发布:手机安全防护软件 编辑:程序博客网 时间:2024/06/05 19:09
  1. 多态,虚函数,纯虚函数
    多态:是对于不同对象接收相同消息时产生不同的动作。C++的多态性具体体现在运行和编译两个方面:
    程序运行时的多态性通过继承和虚函数来体现;
    程序编译时多态性体现在函数和运算符的重载上;
    虚函数:在基类中冠以关键字 virtual 的成员函数。 它提供了一种接口界面。允许在派生类中对基类的虚函数重新定义。
    纯虚函数的作用:在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。作为接口而存在,纯虚函数不具备函数的功能,一般不能直接被调用。
    从基类继承来的纯虚函数,在派生类中仍是虚函数。如果一个类中至少有一个纯虚函数,那么这个类被称为抽象类(abstract class)。
    抽象类中不仅包括纯虚函数,也可包括虚函数。抽象类必须用作派生其他类的基类,而不能用于直接创建对象实例。但仍可使用指向抽象类的指针支持运行时多态性。

  2. 子类析构时要调用父类的析构函数吗?
    析构函数调用的次序是先派生类的析构后基类的析构,也就是说在基类的的析构调用的时候,派生类的信息已经全部销毁了。定义一个对象时先调用基类的构造函数、然后调用派生类的构造函数;析构的时候恰好相反:先调用派生类的析构函数、然后调用基类的析构函数。

  3. 请说出const与#define 相比,有何优点?
    答案:
    const作用:定义常量、修饰函数参数、修饰函数返回值三个作用。被Const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
    1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
    2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。

  4. 内存的分配方式有几种?
    一、从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。
    二、在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
    三、从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

  5. 全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?
    生命周期不同:
    全局变量随主程序创建和创建,随主程序销毁而销毁;局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在;
    使用方式不同:
    通过声明后全局变量程序的各个部分都可以用到;局部变量只能在局部使用,分配在栈区。
    操作系统和编译器通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行的时候被加载。局部变量则分配在堆栈里面


关于x = x & (x - 1)

含义:这条语句执行一次,就会把x用二进制格式表示时的最右边的一个二进制1变为二进制0,因为x-1会将该位(x用二进制表示时最右边的一个二进制1)变为0;
应用1:把一个整数用二进制表示时,其中二进制1的个数;

int Func(int x)  {      int count = 0;      while (x)      {          count ++;          x = x & (x - 1);      }      return count;  }  

设x=9999,其二进制格式为: 10011100001111; 则count=8;
思路:将x转化为二进制格式,统计一下含有的二进制1的个数;
应用2:判断一个整数(x)是否是2的n次方;

int Func(int x)  {      if ((x&(x-1))==0)      {          return true;      }      else      {          return false;      }  }  

思路:如果一个整数是2的n次方,那么,这个数用二进制表示时,其最高位为二进制1,其余位为二进制0;