C++基础知识

来源:互联网 发布:手机注销淘宝账号 后果 编辑:程序博客网 时间:2024/06/10 18:04

1.C++中什么数据分配在栈或堆,静态存储区以及常量存储区中?
栈,里面的变量通常是局部变量、函数参数等。
堆,就是那些由 new 分配的内存块
全局/静态存储区,全局变量和静态变量被分配到同一块内存中
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改
2.C++编译器自动为类产生的四个缺省函数是什么?
默认构造函数、析构函数、拷贝构造函数、赋值函数
3.我们可以用static修饰一个类的成员函数,也可以用const修饰类的而成员函数请问:能不能同时用const和static修饰类的成员函数? 并进行说明.
不可以。C++编译器在实现const的成员函数的时候为了确保该函数不能修改类的实例的状态,会在函数中添加一个隐式的参数const this*。但当一个成员为static的时候,该函数是没有this指针的。也就是说此时const的用法和static是冲突的。
4.在C++中,构造函数是没有返回值的,那么该如何处理构造函数中可能发生的错误(例如资源分配失败)?
Try catch 抛出异常,或者assert
5.请简述C/C++语言中栈空间和堆空间的主要区别.
1申请方式 
stack: 由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间 
heap: 需要程序员自己申请,并指明大小,在c中malloc函数 ,在C++中用new运算符 
2 申请后系统的响应 
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。 
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。 
3申请大小的限制 
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。 
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。 
4申请效率的比较: 
栈由系统自动分配,速度较快。但程序员是无法控制的。 
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便. 
5堆和栈中的存储内容 
栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。 
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。 
6存取效率的比较 
char s1[] = "aaaaaaaaaaaaaaa"; 
char *s2 = "bbbbbbbbbbbbbbbbb"; 
aaaaaaaaaaa是在运行时刻赋值的; 
而bbbbbbbbbbb是在编译时就确定的; 


6.C++处理一场可以有两种方式,一种是throw异常,一种是在函数中return 错误码.你怎么理解这两种方法的优劣.
http://blog.csdn.net/pongba/article/details/1815742
7.为什么析构函数建议加virtual属性
如果delete一个基类的指针时, 如果它指向的是一个子类的对象,那么析构函数不为虚就会导致无法调用子类析构函数,从而导致资源泄露。
8.拷贝构造函数的形参形式是什么样子的?为什么采用这种形式?什么情况下会被调用?
1引用比较高效:如果形参是对象类型的,那么它是否也要实例化? 而且整个对象进行拷贝,效率不高,很不划算。如果形参是指针类型的,从编译的角度来看:程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。
2.形参为对象类型是行不通的:
  复制构造函数也是构造函数,只不过它比较特别而已。如果形参是对象,在被调用时形参也需要实例化(构造)那么它的构造是不是也有点类似于, 形参 = 实参 ;这么说来,这不是在调用复制构造函数麽? 之后调用复制构造函数的形参又要实例化,又调用复制构造函数,造成死循环


通常构造函数只在对象创建时被调用,而拷贝构造函数则在以下3种情况下被调用。
1。当使用类的一个对象去初始化该类的另一个新对象时。
2。如果函数的形参是类的对象,那么当调用该函数时拷贝构造函数也会被调用。
3。如果函数的返回值是类的对象,那么函数执行完成返回调用者时。


9.在C++的语法中有友元函数friend(一个类的成员函数可以作为另一个类的友元,前者可以访问后者对象的私有成员)。但后期的高级语言java和C#
却没有这方面的语法支持,为什么要去掉友元函数,谈谈你的理解。
友元函数会破坏封装和隐藏性质
10.简单说明面向对象的特性及重要性。(额外扩展面向对象的五大基本原则)
三大特性是:封装,继承,多态  
封装,就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。


继承是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;
 
多态是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。


五大基本原则 
单一职责原则SRP(Single Responsibility Principle)
是指一个类的功能要单一,不能包罗万象。
开放封闭原则OCP(Open-Close Principle) 
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。
替换原则(the Liskov Substitution Principle LSP) 
子类应当可以替换父类并出现在父类能够出现的任何地方。
依赖原则(the Dependency Inversion Principle DIP) 具体依赖抽象,上层依赖下层。接口分离原则(the Interface Segregation Principle ISP) 
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来


11. (1)指针和引用的区别是什么
1.指针和引用的定义和性质区别:
(1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。
(2)可以有const指针,但是没有const引用;
(3)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)
(4)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;
(5)指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。
(6)"sizeof引用"得到的是所指向的变量(对象)的大小,而"sizeof指针"得到的是指针本身的大小;
(7)指针和引用的自增(++)运算意义不一样;
2.指针和引用作为函数参数进行传递时的区别。
(1)指针作为参数进行传递:
一级指针传递不会修改实参指针的值。
2.将引用作为函数的参数进行传递。
在讲引用作为函数参数进行传递时,实质上传递的是实参本身,即传递进来的不是实参的一个拷贝,因此对形参的修改其实是对实参的修改,所以在用引用进行参数传递时,不仅节约时间,而且可以节约空间。


(2)malloc/free & new/delete的区别是什么
malloc/free:
函数原型及说明:
void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。
void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。
 2.内存操作:
malloc函数的参数是接受需要分配的内存字节数,如果内存能够满足请求量,那么将会返回:指向被分配的内存块起始位置
free函数释放的是指针指向的内存(不是释放的指针本身,不会删除指针本身),其中指针必须指向所释放内存空间的首地址
 
new/free:
操作时发生事件:
new的时候会有两个事件发生:1).内存被分配(通过operator new 函数)  2).为被分配的内存调用一个或多个构造函数构建对象
delete的时候,也有两件事发生:1).为将被释放的内存调用一个或多个析构函数  2).释放内存(通过operator delete 函数)
特殊应用:
使用delete是未加括号,delete便假设删除对象是单一对象。否则便假设删除对象是个数组。因此,如果在调用new时使用了[],则在调用delete时也使用[],如果你在调用new的时候没有[],那么也不应该在调用时使用[]。
 
malloc/free 和new/delete 的本质区别:
1.malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符
2.new能够自动分配空间大小
3.对于用户自定义的对象而言,用maloc/free无法满足动态管理对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++需要一个能对对象完成动态内存分配和初始化工作的运算符new,以及一个能对对象完成清理与释放内存工作的运算符delete---简而言之 new/delete能进行对对象进行构造和析构函数的调用进而对内存进行更加详细的工作,而malloc/free不能。
 
三、联系
既然new/delete的功能完全覆盖了malloc/free,为什么C++还保留malloc/free呢?因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete,malloc/free必须配对使用。
(3)struct 与 class 的区别是什么
默认访问属性不同
12.虚函数的理解
(1)C++中虚函数的实现机制
基类的虚函数表的创建:首先在基类声明中找到所有的虚函数,按照其声明顺序,编码0,1,2,3,4……,然后按照此声明顺序为基类创建一个虚函数表,其内容就是指向这些虚函数的函数指针,按照虚函数声明的顺序将这些虚函数的地址填入虚函数表中。
对于子类的虚函数表:首先将基类的虚函数表复制到该子类的虚函数表中。若子类重写了基类的虚函数,则将子类的虚函数表中存放的函数地址(未重写前存放的是子类的虚函数的函数地址)更新为重写后函数的函数指针。若子类增加了一些虚函数的声明,则将这些虚函数的地址加到该类虚函数表的后面。
当调用pBase->show();时,执行的步骤:
1判断Base类中show是否为虚函数。
2若不是虚函数则找到pBase所指向的对象所属类Base。执行Base::show()。若是虚函数则执行步骤3.
3访问pBase所指对象的虚函数表指针得到pBase所指对象所在类的虚函数表。
4 查找Base中show()在声明时的位序为x,到步骤3得到的虚函数表中找到位序x,从而得到要执行的show的函数地址。
5根据函数地址和Base中声明的show的函数类型(形参和返回值)访问地址所指向的函数。
(2)对一个包含虚函数成员的对象bzero()会有什么问题


13.请简单描述数组(vector)与链表(list)的区别以及应用场景。
vector拥有一段连续的内存空间,并且起始地址不变,因此  它能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当该数组后的内存空间不够时,需要重新申请一块足够大的内存并进行内存的拷贝。这些都大大影响了vector的效率。  
   
List就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间可以是不连续  的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除和插入。   
    
因此在实际使用时,如何选择哪一个,应根据你的需要而定,一般应遵循下面  的原则:  
 1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector  
 2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list
14.C++语言中的函数参数传递方式有哪几种?从功能,效率,安全,灵活性等方面比较一下。
按值传递(pass by value):首先计算出实参表达式的值,接着给对应的形参变量分配一个存储空间,该空间的大小等于该形参类型的,然后把以求出的实参表达式的值一一存入到形参变量分配的存储空间中,成为形参变量的初值,供被调用函数执行时使用。这种传递是把实参表达式的值传送给对应的形参变量,故称这种传递方式为“按值传递”。使用这种方式,调用函数本省不对实参进行操作,也就是说,即使形参的值在函数中发生了变化,实参的值也完全不会受到影响,仍为调用前的值。
地址传递(pass by pointer):如果在函数定义时将形参说明成指针,对这样的函数进行调用时就需要指定地址值形式的实参。这时的参数传递方式就是地址传递方式。
 引用传递(pass by reference):地址传递与按值传递的不同在于,它把实参的存储地址传送给对应的形参,从而使得形参指针和实参指针指向同一个地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。
按值传递方式容易理解,但形参值的改变不能对实参产生影响。
地址传递方式虽然可以使得形参的改变对相应的实参有效,但如果在函数中反复利用指针进行间接访问,会使程序容易产生错误且难以阅读。
 如果以引用为参数,则既可以使得对形参的任何操作都能改变相应的数据,又使得函数调用显得方便、自然。引用传递方式是在函数定义时在形参前面加上引用运算符“&”。
15.描述观察者模式及其实现过程,并举例说明你是怎么使用观察者模式的
http://blog.csdn.net/u012395430/article/details/26623859


16、static 局部变量和普通局部变量有什么区别?
生命周期不同,static局部变量只被初始化一次,下一次依据上一次结果值;
17、友元函数与成员函数的区别是什么?
成员函数是类定义的一部分,通过特定的对象来调用。成员函数可以隐式访问调用对象的成员,而无须使用成员操作符。友元函数不是类的组成部分,因此被称为直接函数调用。友元函数不能隐式访问类成员,而必须将成员操作符用于作为参数传递的对象。友元函数不能被继承。
18、在C++程序中调用被C编译器编译后的函数,为什么要加extern c ?
以C的规则编译C++代码
19.面向对象的三个基本特征,请简单描述。
描述过,在上面
20.简述面向对象及面向过程的定义并回答为何要在软件工程中采用面向对象的思想。
面向对象是把构成问题的事务分解成各个对象,而建立对象的目的也不是为了完成一个个步骤,而是为了描述某个事物在解决整个问题的过程中所发生的行为。
面向过程是分析解决问题的步骤,然后用函数把这些步骤一步一步的实现,然后在使用的时候一一调用则可。
面向对象保证了功能的统一型,从而为扩展打下基础。
21.请简述深拷贝和浅拷贝的定义。
深拷贝:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
22.请简述static, const, inline 的定义及用法。
http://www.jb51.net/article/41629.htm
(实在太长了^.^)
23.简述多态作用及应用方式?
多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。C++中,实现多态有以下方法:虚函数,抽象类,覆盖,模板(重载和多态无关)。C++中的多态性具体体现在运行和编译两个方面。运行时多态是动态多态,其具体引用的对象在运行时才能确定。编译时多态是静态多态,在编译时就可以确定对象使用的形式。
24.为什么类的静态成员函数不能直接访问类得非静态成员变量?
没有this指针
25.c++中,什么函数不能声明为虚函数?为什么?
普通函数
普通函数(非成员函数)只能被overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时邦定函数。多态的运行期行为体现在虚函数上,虚函数通过继承方式来体现出多态作用,顶层函数不属于成员函数,是不能被继承的
构造函数
因为构造函数本来就是为了明确初始化对象成员才产生的,然而virtual function主要是为了再不完全了解细节的情况下也能正确处理对象。另外,virtual函数是在不同类型的对象产生不同的动作,现在对象还没有产生,如何使用virtual函数来完成你想完成的动作。
(1)构造函数不能被继承,因而不能声明为virtual函数
(2)构造函数一般是用来初始化对象,只有在一个对象生成之后,才能发挥多态
作用,如果将构造函数声明为virtual函数,则表现为在对象还没有生成的情况下就使用了多态机制,因而是行不通的。
内联成员函数
内联函数就是为了在代码中直接展开,减少函数调用花费的代价,虚函数是为了在继承后对象能够准确的执行自己的动作,这是不可能统一的。(inline函数在编译时被展开,虚函数在运行时才能动态的邦定函数)
inline函数和virtual函数有着本质的区别,inline函数是在程序被编译时就展开,在函数调用处用整个函数体去替换,而virtual函数是在运行期才能够确定如何去调用的,因而inline函数体现的是一种编译期机制,virtual函数体现的是一种运行期机制。此外,一切virtual函数都不可能是inline函数。
静态成员函数
静态成员函数对于每个类来说只有一份代码,所有的对象都共享这一份代码,他也没有要动态邦定的必要性。不能被继承,只属于该类。
友元函数
因为C++不支持友元函数的继承,对于没有继承特性的函数没有虚函数的说法。友元函数不属于类的成员函数,不能被继承。
26.C++中虚函数如何定义,使用时应该注意什么?
如上
27.C++拷贝构造函数和赋值用算符有那些不同和相同点?
相同点:实现复制功能
不同点:copy:源对象存在而目标对象未被创建
=:源对象和目标对象都不存在
28.评价多继承的优点和缺点。
多重继承的优点是对象可以调用多个基类中的接口具备多个基类的特性。
多重继承的缺点是容易出现继承向上的二义性,会造成冗余和浪费。
29.什么是虚指针?
用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。
存在虚函数的类都有一个一维的虚函数表叫做虚表。类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。


30.虚函数的入口地址和普通函数有什么不同?
每个虚函数都在vtable中占了一个表项,保存真一条跳到它的入口地址的指令(实际上就是保存了它的入口地址)。当一个包含虚函数的对象(注意,不是对象的指针)被创建的时候,它在头部附加了一个指针,指向vtable中相应的位置。
调用虚函数的时候,不管你是用什么指针调用,它先根据vtable找到入口地址再执行,从而实现了“动态联编”。


普通函数只是简单的跳到一个固定的地址。


31.
1、C++中如何阻止一个类被实例化?
使用抽象类,或者将构造函数声明为private。
2、一般在什么时候构造函数被声明成private呢?
比如要阻止编译器生成默认的拷贝构造函数的时候。
3、什么时候编译器会生成默认的 copy constructor呢?
只要自己没写,而程序需要,都会生成。
4、如果你已经写了一个拷贝构造函数,编译器还会生成copy constructor?

32.structure是否可以拥有constructor/destructor以及成员函数?
如果可以那么structor和class有什么区别.
可以,区别在上面。
33.析构函数可以是内联函数吗?
可以。
34.编写string的构造函数,析构函数,和赋值函数。
//普通构造函数 
String::String(const char *str) 

        if(str==NULL) 
        { 
                m_data = new char[1]; // 得分点:对空字符串自动申请存放结束标志'\0'的//加分点:对m_data加NULL 判断 
                *m_data = '\0'; 
        }    
        else 
        { 
         int length = strlen(str); 
         m_data = new char[length+1]; // 若能加 NULL 判断则更好 
         strcpy(m_data, str); 
        } 

// String的析构函数 
String::~String(void) 

        delete [] m_data; // 或delete m_data; 

//拷贝构造函数 
String::String(const String &other)    // 得分点:输入参数为const型 
{     
        int length = strlen(other.m_data); 
        m_data = new char[length+1];     //加分点:对m_data加NULL 判断 
        strcpy(m_data, other.m_data);    

//赋值函数 
String & String::operate =(const String &other) // 得分点:输入参数为const 型 
{     
        if(this == &other)                    //得分点:检查自赋值 
                return *this;   
        delete [] m_data;                //得分点:释放原有的内存资源 
        int length = strlen( other.m_data );      
        m_data = new char[length+1];  //加分点:对m_data加NULL 判断 
        strcpy( m_data, other.m_data );   
        return *this;             //得分点:返回本对象的引用  





35.什么是多态?
在上面
36.重载和覆盖有什么不同?
重载与覆盖的区别
1、方法的覆盖是子类和父类之间的关系,是垂直关系;方法的重载是同一个类中方法之间的关系,是水平关系。
2、覆盖只能由一个方法,或只能由一对方法产生关系;方法的重载是多个方法之间的关系。
3、覆盖要求参数列表相同;重载要求参数列表不同。
4、覆盖关系中,调用那个方法体,是根据对象的类型(对象对应存储空间类型)来决定;重载关系,是根据调用时的实参表与形参表来选择方法体的。
37.  what is v-table and v-ptr in C++? what is the relationship between them?
在上面
38.C和C++中如何让动态分配合释放内存?他们的区别是什么?
Malloc和new的那个就是,在上面
40.C和C++的struct有什么不同
C语言中:Struct是用户自定义数据类型(UDT)。
C++语言中:Struct是抽象数据类型(ADT),支持成员函数的定义。struct的成员的默认访问说明符为public,class为private。
C:struct是没有权限设置的。 
C++:struct增加了访问权限,且可以和类一样有成员函数。 
C++中的struct等同于class,只是class默认成员权限是private,而struct默认成员权限是public。
在标准C++中,struct和class有两个区别: 
第一:struct中的成员默认是public的,class中的默认是private的。 
第二:在用模版的时候只能写template <class Type>或template <typename Type>不能写template <struct Type>。 
此外,如果没有多态和虚拟继承,在C++中,struct和class的存取效率完全相同!简单的说就是,存取class的data member和非virtual function效率和struct完全相同!不管该data member是定义在基类还是派生类的。 
C++:struct可以当作class来用,他和C++中class的唯一的区别是,class中的成员默认是private,而struct的成员默认为public。
C:struct只能是一些变量的集合体,可以封装数据却不可以隐藏数据,而且成员不可以是函数。
如果不是为了和C兼容,C++中就不会有struct关键字。
41. 为了实现C++中的多态性,编译器做了哪些事情?也就是说C++语言内部怎么实现多态?
在上面
42. 函数前的static和volatile变量中关键字作用
volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,
遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
static 声明的变量在C语言中有两方面的特征:
1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
43. 使用C++赋值运算符应注意什么地方?(答案是重载的情况下)
1. 返回类型
必须为该类型的引用
原因:必须返回一个引用,才可以允许连续赋值 ;
必须返回自身实例的引用(*this)
2. 参数
传入参数申明为常量引用
如果传入的参数不是引用而是实例,那么从形参到实参会调用一次复制构造函数;
传入参数和当前的实例(*this)是否为同一实例.
3. 释放实例自身已有的类型,防止内存泄露;


4. 考虑当因内存不足在new char时候抛出异常


44.请用你熟悉的开发语言实现一个单例模型Singleton(单例模型:即只有一个对象的类)
面试题讲
45.用C++语言实现单例模式(Singleton)时,如何确保调用者无法通过正常手段创建出第二个对象?
构造函数私有
46.简述C++语言中的dynamic_cast相对于C语言中强制类型转换的必要性.
1.用在多态的子类情况下,父类不能提供处理接口,这时可以针对子类做特殊的处理。
2.dynamic_cast比另外3个cast优势就是会对转换进行检查,如果出错,会报错。

原创粉丝点击