问题整理

来源:互联网 发布:ubuntu安装cuda caffe 编辑:程序博客网 时间:2024/04/28 03:47

1.在什么情况下析构函数必须是虚函数

   若类中有虚函数这个类的析构函数应该是虚的析构函数,否则会有错,假设父类为a,子类为b

   当 a* p = new b();要析构p指向的对象时,若a中的析构函数不是virtual则调用 delete p 时,不会调用b的析构函数(构造函数调用 是先基类baseClass后继承类),这样在b中分配的资源就无法释放了。你可以在ab的析构函数中输出看一下,或者用调试工具跟踪看一下。

 

2.在全局变量和全局静态变量有什么区别

变量可以分为:全局变量、静态全局变量、静态局部变量和局部变量

按存储区域分:全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区(内存分区:全局/静态存储区,常量存储区,堆,栈,自由存储区)

按作用域分:静态全局变量在整个工程文件内都有效;全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效       

初始化:全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。静态全局变量,只本文件可以用。 全局变量是没有定义存储类型的外部变量,作用域是从定义点到程序结束.省略了存储类型符,系统将默认为是自动型静态全局变量是定义存储类型为静态型的外部变量,作用域是从定义点到程序结束,所不同的是存储类型决定了存储地点,静态型变量是存放在内存的数据区中, 它们在程序开始运行前就分配了固定的字节,在程序运行过程中被分配的字节大小是不改变的.只有程序运行结束后,才释放所占用的内存

自动型变量存放在堆栈区中.堆栈区也是内存中一部分,该部分内存在程序运行中是重复使用的。

 

3.声明与定义有什么区别

声明是向编译器介绍名字--标识符。它告诉编译器这个函数或变量在某处可找到,它的模样象什么。而定义是说:在这里建立变量在这里建立函数它为名字分配存储空间。无论定义的是函数还是变量,编译器都要为它们在定义点分配存储空间。对于变量,编译器确定变量的大小,然后在内存中开辟空间来保存其数据,对于函数,编译器会生成代码,这些代码最终也要占用一定的内存。

CC++中,可以在不同的地方声明相同的变量和函数,但只能有一个定义(有时这称为ODR,单一定义规则)。定义也可以是声明,如果有int   x;,之前编译器未发现标识符x,编译器则把这一标识符看成是定义并立即为它分配存储空间  

函数声明包括函数类型、函数名、参数列表和一个分号,这些信息足以编译器认出它是一个函数声明并可识别出这个函数的外部特征。由此推断,变量声明应是类型标识后面跟一个标识符。    int   a;      但这产生了一个矛盾,这段代码有足够的信息让编译器为之分配存储空间,而且编译器也确实给之分配了存储空间。要解决这个问题,对于CC++需要一个关键字来说明这是一个声明,它的定义在别的地方,这个关键字就是extern(声明函数),它表示变量是在文件以外定义的,或在文件后面定义的。

在变量定义前加extern表示声明一个变量但不定义它

如:     extern   int   a;    

extern也可用于函数声明,

如:     extern   int   func1(int   length,int   width);    

但 由于没有函数体,编译器必把它当成声明而非定义,extern对于函数来说是多余的、可选的C语言的设计者并不要求函数声明使用extern,这可能有 些令人遗憾,如果函数声明也要求用extern,那么形式上与变量声明更加一致了,从而减少了混乱(但这就需要更多的输入,这也许能解释为什么不要求函数声明使用extern的原因)

 

4.什么是字节对齐,为什么要对齐? 

   现代计算机中内存空间都是按照byte分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐

    对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。

 

 

原创粉丝点击