如何理解c/c++和php语言的区别( 六 )


46. 纯虚函数如何定义?含有纯虚函数的类称为什么?为什么析构函数要定义成虚函数?
纯虚函数是在基类中声明的虚函数 , 它在基类中没有定义 , 但要求任何派生类都要定义自己的实现方法 。纯虚函数是虚函数再加上= 0 。virtual void fun ()=0 。含有纯虚函数的类称为抽象类在很多情况下 , 基类本身生成对象是不合情理的 。例如 , 动物作为一个基类可以派生出老虎、孔雀等子类 , 但动物本身生成对象明显不合常理 。同时含有纯虚拟函数的类称为抽象类 , 它不能生成对象 。如果析构函数不是虚函数 , 那么释放内存时候 , 编译器会使用静态联编 , 认为p就是一个基类指针 , 调用基类析构函数 , 这样子类对象的内存没有释放 , 造成内存泄漏 。定义成虚函数以后 , 就会动态联编 , 先调用子类析构函数 , 再基类 。
47. C++中哪些不能是虚函数?
1)普通函数只能重载 , 不能被重写 , 因此编译器会在编译时绑定函数 。
2)构造函数是知道全部信息才能创建对象 , 然而虚函数允许只知道部分信息 。
3)内联函数在编译时被展开 , 虚函数在运行时才能动态绑定函数 。
4)友元函数 因为不可以被继承 。
5)静态成员函数 只有一个实体 , 不能被继承 。父类和子类共有 。
48. 类型转换有哪些?各适用什么环境?dynamic_cast转换失败时 , 会出现什么情况(对指针 , 返回NULL.对引用 , 抛出bad_cast异常)?
静态类型转换 , static_cast , 基本类型之间和具有继承关系的类型 。
例子A,double类型转换成int 。B,将子类对象转换成基类对象 。
常量类型转换 , const_cast, 去除指针变量的常量属性 。
无法将非指针的常量转换为普通变量 。
动态类型转换 , dynamic_cast , 运行时进行转换分析的 , 并非在编译时进行 。dynamic_cast转换符只能用于含有虚函数的类 。dynamic_cast用于类层次间的向上转换和向下转换 , 还可以用于类间的交叉转换 。在类层次间进行向上转换 , 即子类转换为父类 , 此时完成的功能和static_cast是相同的 , 因为编译器默认向上转换总是安全的 。向下转换时 , dynamic_cast具有类型检查的功能 , 更加安全 。类间的交叉转换指的是子类的多个父类之间指针或引用的转换 。该函数只能在继承类对象的指针之间或引用之间进行类型转换 , 或者有虚函数的类 。
49. 如何判断一段程序是由C 编译程序还是由C++编译程序编译的?
#ifdef __cplusplus
cout<<"C++";
#else
cout<<"c";
#endif
50. 为什么要用static_cast转换而不用c语言中的转换?
Static_cast转换 , 它会检查类型看是否能转换 , 有类型安全检查 。
比如 , 这个在C++中合法 , 但是确实错误的 。
A* a= new A;
B* b = (B*)a;
51. 操作符重载(+操作符) , 具体如何去定义?
除了类属关系运算符”.”、成员指针运算符”.*”、作用域运算符”::”、sizeof运算符和三目运算符”?:”以外 , C++中的所有运算符都可以重载 。
<返回类型说明符> operator <运算符符号>(<参数表>){}
重载为类的成员函数和重载为类的非成员函数 。参数个数会不同 , 应为this指针 。
52. 内存对齐的原则?
A.结构体的大小为最大成员的整数倍 。
B.成员首地址的偏移量为其类型大小整数倍 。
53. 内联函数与宏定义的区别?
内联函数是用来消除函数调用时的时间开销 。频繁被调用的短小函数非常受益 。
A. 宏定义不检查函数参数 , 返回值什么的 , 只是展开 , 相对来说 , 内联函数会检查参数类型 , 所以更安全 。
B. 宏是由预处理器对宏进行替代 , 而内联函数是通过编译器控制来实现的
54. 动态分配对象和静态分配对象的区别?
动态分配就是用运算符new来创建一个类的对象 , 在堆上分配内存 。
静态分配就是A a;这样来由编译器来创建一个对象 , 在栈上分配内存 。


推荐阅读