2.25
-
如何理解封装、继承和多态?(它们分别解决了什么问题)
(1)封装
封装是面向对象的核心思想,将对象的属性
和行为
封装起来,不需要让外界知道具体实现细节,这就是封装思想。防止代码(数据)被破坏。
(2)继承
继承主要描述的就是类
与类
之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展
。
(3)多态
多态(包含多态)指的是在一个类中定义的属性和功能被其他类继承
后,子类重写
父类函数,当把子类对象
直接赋值给父类引用/指针
变量时,相同引用类型的变量调用同一个方法所呈现出的多种不同行为特性。 -
C++内存四区存在的意义是什么(代码区、全局区、堆区和栈区)
(1)代码区
这个区域存放函数体的二进制代码,是由操作系统进行管理的。
(2)全局区
全局区主要是用来存放全局变量和静态常量(即使用static关键字定义的变量),里面有细分出一个常量区。要注意局部变量和局部常量是不属于这个区域的。
该区域是在程序结束后由操作系统释放。
(3)栈区
由编译器自动分配释放,存放函数的形参、局部变量等。当函数执行完毕时自动释放。
(4)堆区
一般由程序员手动分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回收。与栈区最大的区别就是,堆区的变量都是我们自己分配和释放的。在学习C语言的时候我们学习了动态内存分配函数malloc,以及其释放函数free。在C++中,起到相同功能的是函数new和delete, -
static 和const分别怎么用,类里面static和const能否同时修饰成员函数:
static:
(1)对局部变量:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置
(从原来的栈中存放改为静态存储区)及其生命周期
(局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存当中,直到程序结束,只不过我们不能再对他进行访问),但未改变其作用域。
(2)对全局变量:static修饰全局变量,并未改变其存储位置及生命周期,而是改变了其作用域
,使当前文件外的源文件无法访问该变量,好处如下:①不会被其他文件所访问,其他文件中可以使用相同名字的变量,不会发生冲突。对全局函数也是有隐藏作用。②而普通全局变量只要定义了,任何地方都能使用,使用前需要声明所有的.c文件,只能定义一次普通全局变量,但是可以声明多次(外部链接)。注意:全局变量的作用域是全局范围,但是在某个文件中使用时,必须先声明。
(3)对类成员变量:用static修饰类的数据成员实际使其成为类的全局变量,会被类的所有对象共享,包括派生类的对象。因此,static成员必须在类外进行初始化(初始化格式: int base::var=10;),而不能在构造函数内进行初始化,不过也可以用const修饰static数据成员在类内初始化 。
- 不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误
- 静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以
- 静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的指针或引用
(4)对类成员函数:不可以同时用const和static修饰成员函数。
C++编译器在实现const的成员函数的时候为了确保该函数不能修改类的实例的状态,会在函数中添加一个隐式的参数const this*。但当一个成员为static的时候,该函数是没有this指针的
。也就是说此时const的用法和static是冲突的。static的作用是表示该函数只作用在类型的静态变量上,与类的实例没有关系;而const的作用是确保函数不能修改类的实例的状态
const
(1) 限定变量为不可修改。
(2) 限定成员函数不可以修改任何数据成员。
(3) 声明常对象,只能调用常成员函数
const与指针:
const char p 表示 指向的内容不能通过p改变,但是p还可以指向其他对象。
char * const p,就是将p声明为常指针,指向不变,但指向内容可以改变。(数组名和this指针都是指针常量)
2.26
-
组合类的初始化顺序是怎样的:
(1)调用内嵌对象的构造函数,调用顺序按照内嵌对象在组合类中定义的顺序,而与构造函数初始化列表中出现的顺序无关;
(2)执行类构造函数体; -
函数指针的定义方式是怎样的?有什么含义?函数指针有什么用途?()
(1)每个函数都有函数名,就是函数代码在内存中起始地址。所以函数名(参数表)就是函数代码首地址(参数表);
数据类型 (* 函数指针名)(形参表) //声明
函数指针名=函数名; //赋值
(2)函数指针就是专门存放函数代码首地址的变量,定义时用typedef int (*fptr)(double);这里声明了fptr为“一个返回int类型,参数是double类型的函数指针"的类型别名;可以用fprt fp来声明这一类型变量。直接用函数指针名(参数表)
来调用某个函数。
(3)①函数的指针变量不是固定指向哪一个函数的,而只是表示定义了一个这样类型的变量,它是专门用来存放函数的入口地址的;在程序中把哪一个函数的地址赋给它,它就指向哪一个函数。②函数指针变量常用的用途之一是把指针作为参数传递到其他函数
int (*p)(int a, int b); //p是一个指向函数的指针变量,所指函数的返回值类型为整型
int *p(int a, int b); //p是函数名,此函数的返回值类型为整型指针
2.27
-
静态变量和动态变量初始化有什么相同点和不同点?
(1)存储位置、生存周期、作用域
动态变量:存储在内存出栈数据区,根据你定义的位置确定,比如你在一个函数中定义的,那么超出该函数范围变量将失效
静态变量:存储在全局数据区(静态数据区),程序结束时才释放
(2)初始化时机
变量的静态初始化是预编译
时对变量进行初始化,而动态初始化,是在程序运行
时,根据需要,动态分配空间并赋值。
(3)初始化赋值
动态变量如果不赋初值,其初值是不确定的,静态变量如果不赋初值,会被初始化为0 -
比较值传递和引用传递的相同的和不同点?
(1)值传递:将实参的值传递给形参;形参是实参的“替身”,但只是值复制过来一样而已。因此,形参有自己独立的存储空间。
(2)使用引用传递可以通过形参的值直接改变实参的值,而使用值传递不可以