编程之法:A.1语言基础

来源:互联网 发布:饥荒联机版网络红色 编辑:程序博客网 时间:2024/05/20 09:09

A1.语言基础

1. C++中虚拟函数的实现机制

答:关键字:虚函数底层实现机制;虚函数表;虚表指针
编译器处理虚函数的方法是:为每个类对象添加一个隐藏成员,隐藏成员中保存了一个指向函数地址数组的指针,称为虚表指针(vptr),这种数组成为虚函数表(virtual function table, vtbl),即,每个类使用一个虚函数表,每个类对象用一个虚表指针。
举个例子:基类对象包含一个虚表指针,指向基类中所有虚函数的地址表。派生类对象也将包含一个虚表指针,指向派生类虚函数表。看下面两种情况:
如果派生类重写了基类的虚方法,该派生类虚函数表将保存重写的虚函数的地址,而不是基类的虚函数地址。
如果基类中的虚方法没有在派生类中重写,那么派生类将继承基类中的虚方法,而且派生类中虚函数表将保存基类中未被重写的虚函数的地址。注意,如果派生类中定义了新的虚方法,则该虚函数的地址也将被添加到派生类虚函数表中。

2. 描述指针数组和数组指针的区别

答:指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身的大小决定,每一个元素都是一个指针,在32 位系统下任何类型的指针永远是占4 个字节。它是“储存指针的数组”的简称。
数组指针:首先它是一个指针,它指向一个数组。在32 位系统下任何类型的指针永远是占4 个字节,至于它指向的数组占多少字节,不知道,具体要看数组大小。它是“指向数组的指针”的简称。

3. malloc-free和new-delete的区别

答:相同点:都可用于动态内存分配与释放;
不同点:1)malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符;
2)new自动计算需要分配的空间,而malloc需要手工计算计算字节数;例如:int *p=new int[3]; int *pp=malloc(sizeof(int)*3);
3)new是类型安全的,而malloc不是;
4)new调用operator new分配足够的空间,并调用相关对象的构造函数,而malloc不能调用构造函数;
delete调用相关对象的析构函数,然后调用operator delete以释放空间,而malloc不能调用析构函数;
5)malloc/free需要库文件支持,new/delete则不需要。

4.sizeof和strlen的区别

答:1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。
该类型保证能容纳实现所建立的最大对象的字节大小。
2.sizeof是运算符,strlen是函数。
3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以”\0”结尾的。
sizeof还可以用函数做参数,比如:
short f();
printf(“%d\n”, sizeof(f()));
输出的结果是sizeof(short),即2。
4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。
5.大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因
char str[20]=”0123456789”;
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;
6.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。
7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
8.当适用了于一个结构类型时或变量, sizeof 返回实际的大小,
当适用一静态地空间数组, sizeof 归还全部数组的尺寸。
由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。

5.描述函数调用的整个过程

答:函数调用的整个执行过程分成4步:
1)创建形参变量,为每个形参变量建立相应的存储空间。
2)值传递,即将实参的值复制到对应的形参变量中。
3)执行函数体,执行函数体中的语句。
4)返回(带回函数值、返回调用点、撤消形参变量)。

6.C++STL中的vector的实现机制,在调用push_back成员函数时,如何实现?

答:STL中vector的实现原理:
vector的数据安排以及操作方式与array非常类似。两者的唯一差别在于空间的运用的灵活性。
array是静态空间,一旦配置好了就不能再改变了。如果程序需要一个更大空间的array,只能自己再申请一个更大的array,然后将以前array中的内容全部拷贝到新的array中。
vector是动态空间,随着元素的加入,它的内部机制会自动扩充空间以容纳新的元素。
vector的关键技术在于其对大小的控制以及重新配置时的数据移动效率。
vector采用的数据结构很简单:线性的连续空间。
它以两个迭代器start和finish分别指向配置得来的连续空间中目前已经被使用的空间。
为了降低空间配置时候的速度,vector实际配置的大小可能比客户端需求量更大一些,以备将来可能的扩充。
如果vector在增加一个元素的时候,超过了自身最大的容量。vector则将自身的容量扩充至原来的两倍。
扩充空间需要经过的步骤:重新配置空间,元素移动,释放旧内存空间。
一旦vector空间重新配置,则指向原来vector的所有迭代器都失效了,因为vector的地址改变了。
这种实现体现到vector实现就是每当push_back一个元素,都要重新分配一个大一个元素的存储,然后将原来的元素拷贝到新的存储,之后在拷贝push_back的元素,最后要析构原有的vector并释放原有的内存。

7.C++STL中的clear

答:调用析构函数,clear没有释放内存,clear只是将数组中的元素置为空,释放内存需要delete。vector::erase()用于清空容器中的内容以及释放内存,并返回指向删除元素的下一个元素的迭代器。

原创粉丝点击