1.new delete与malloc free的联系与区别
都是在堆上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new会自动调用对象的构造函数。delete会调用对象的destructor,而free不会调用对象的destructor。
2.有哪几种情况只能用intialization list 而不能用assignment
当类中含有const、reference成员变量;基类的构造函数都需要初始化表。
3.main函数执行以前,还会执行什么代码
全局对象的构造函数会再main函数之前执行
4.struct 和class的区别
struct的成员默认是共有的,而类的成员默认是私有的。struct和class在其他方面是功能相当的。
5.当一个类A中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零(autodesk)
肯定不是零,举个例子,如果是零的话,声明一个class A[10]对象组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]...
6.请说出const与#define 相比,有何优点
a.const常量有数据类型,而宏常量没有数据类型,编译器可以对前者进行类型安全检查。而对后者只进行字符替换,有没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
b.有些集成化的调式工具可以对const常量进行调式,但是不能对宏进行调试
7.类成员函数的重载、覆盖和隐藏区别
a.成员函数被重载的特征:
1.相同的范围(在同一个类中)
2.函数名字相同
3.参数不同
4.virtual关键字可有可无
b.覆盖是指派生类函数覆盖基类函数,特征是:
1.不同的范围(分别位于派生类与基类)
2.函数名字相同
3.参数相同
4.基类函数必须有virtual关键字
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
1.如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)
2.如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字,此时,基类的函数被隐藏(注意别于覆盖混淆)
8.如何打印出当前源文件的文件名以及源文件的当前行号
cout<<_FILE_;
cout<<_LINE_
_FILE_和_LINE_是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的
9.如何判断一段程序是由C变异程序还是由C++编译程序的?
#ifdef __cplusplus
cout<<"C++";
#else
cout<<"c"
#endif
10.虚函数的本质和实现机制
虚函数的本质是通过基类访问派生类定义的函数。虚函数只能借助于指针或者引用来达到多态效果
11.C++中传递函数参数的方式及他们的优缺点
C++语言中,函数的参数和返回值的传递方式有三种:值传递,指针传递,引用传递
12.什么是多态,C++的多态通过哪些方式实现
多态就是相同的方法呈现出不同的行为
C++的多态主要分为编译时刻的多态,运行时刻的多态
编译时刻的多态通过重载函数实现
运行时刻的多态通过虚函数来实现
13.什么是STL
标准模板库
14.STL六大组件
容器,算法,迭代器,仿函数,配接器,配置器
15.STL的7中主要容器
vector list deque map multimap set multiset
16.你如何理解MVC,举个例子
MVC主要应用了观察者模式与策略模式
MFC里面的文档试图架构是一个MVC模式
17.多重继承如何消除向上继承的二义性
使用虚拟继承即可
18.为什么要引入抽象基类和纯虚函数
主要是为了实现一种接口的效果
19.面向对象四大基本特征
抽象,封装,继承,多态
20.拷贝构造函数相关问题,深拷贝,浅拷贝,临时对象等
深拷贝意味着拷贝了资源和指针,而浅拷贝只是拷贝了指针,没有拷贝资源
这样使得两个指针指向同一个资源,造成同一份析构两次,程序崩溃。
临时对象的开销比局部对象小些。
21.构造函数可否是虚函数,为什么,析构函数呢,可否是纯虚函数
构造函数不能为选函数,要构造一个对象,必须清楚的知道要构造什么,否则无法构造一个对象。析构函数可以为纯虚函数。
22.析构函数的作用
主要是为了避免内存泄露
一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄露
Base *p=new Derived;
p->DoSomething();
delete p;
如果不是析构函数,派生类的析构函数就不会被调用,造成内存泄露
23.指针与引用有什么区别,如果传引用比传指针安全,为什么,如果我使用常量指针难道不行吗
a.引用在创建的同时必须初始化,及应用到一个有效地额对象,而指针在定义的时候不必初始化,可以在定义后面的任何地方重新复制
b.不存在NULL引用,引用必须与合法的存储单元关联,而指针则可以是NULL
c.引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,而指针在任何时候都可以改变为指向另一个对象,给引用赋值并不是改变它和原始对象的绑定关系。
d.引用的创建和销毁并不会调用累的拷贝构造函数
e.语言层面,引用的用法和对象一样,在二进制层面,引用一般都是通过指针来实现的。
只不过编译器帮我们完成了转换
不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,显得很安全
const指针仍然存在空指针,并且有可能产生野指针
总的来说:引用既有指针的效率,又具备变量使用的方便性和直观性。
24.返回引用的函数有什么作用
使函数可以出现在表达式的左边
在重载=运算符中返回引用,则a=b=c这样的表达式是合法的
25.#与##作用
#define string(a) #a
cout<<string(programming is fun);
编译器处理为:
cout<<"programming is fun";
#define concate(a,b) a##b
int xy=10;
cout<<concate(x,y);
编译处理为:
cout<<xy;即输出变量xy的值10
26.C++编译器在匹配函数是遵循的约定
寻找一个参数完全匹配的函数,如果找到了,就调用它
寻找一个函数模板,把它实例化为一个匹配的模板函数,如果找到了,就调用它
尝试寻找一个函数,经过隐式的类型转换,对所给的参数匹配。如果找到了,就调用它。
如果上述方法找不到一个合适的函数,则返回错误
如果第一步有多于一个选择,则返回错误。
27.C++拷贝构造函数的参数圆形是什么样的。如果拷贝构造函数的参数不是对象引用会造成什么情况。
拷贝构造函数的参数是对象的引用或者const对象的引用
如果不是对象的引用而采用对象类型作为参数会出现无限递归。