C++常见面试题总结(1)

一、接口和抽象类的区别:
1。接口只给出方法声明,而不实现。抽象类中可以有方法的实现。
2。接口中不能包含常量、字段(域)、构造函数、析构函数、静态成员。抽象类可以。
3。接口可以多继承,抽象类不行。
4。接口中的所有成员默认为public,因此接口中不能有private修饰符。抽象类可以有私有成员数据


相同点:
(1) 都可以被继承
(2) 都不能被实例化
(3) 都可以包含方法声明
(4) 派生类必须实现未实现的方法
二、static和const的特点:
1。static:static修饰的变量在静态区。
1) 修饰局部变量时,若未初始化,默认值为0。当定义它的函数或者语句块结束的时候,作用域随之结束
2)修饰全局变量时,若未初始化,默认值为0。作用域在定义处到文件结尾。其他文件不能访问。这样其他文件中可以使用相同名字的变量,不会发生冲突。
3)修饰类内成员变量时,使其成为类的全局变量,会被类的所有对象共享,包括派生类的对象。因此,static成员必须在类外进行初始化,而不能在构造函数内进行初始化,不过也可以用const修饰static数据成员在类内初始化 。(也就是说static和const可以同时修饰一个变量)
4)修饰类内成员函数时,函数不含this指针。
可以独立访问,无须创建任何对象实例就可以访问。
当static成员函数在类外定义时不需要加static修饰符。
在静态成员函数的实现中不能直接引用类中的非静态成员,可以引用类中的静态成员。(不能同时使用const和static修饰成员函数。因为const修饰的函数不能修改类的实例,在函数中添加一个const this*指针 ,static修饰的函数没有this指针。
2。const:
1)const修饰变量使其变成常量。
2)修饰成员函数使其不能修改任何数据成员。函数内部不能调用非const函数。可以访问数据成员。
3)修饰对象时,不能访问非const函数,不能修改数据成员(public)但是可以访问。
const可以使程序增强健壮性。

const在 * 前,地址不可变,const在 * 后,值不可变


define和const的区别:
参考自:
(http://blog.csdn.net/love_gaohz/article/details/7567856)
(1) 编译器处理方式不同
  define宏是在预处理阶段展开。
  const常量是编译运行阶段使用。
(2) 类型和安全检查不同
  define宏没有类型,不做任何类型检查,仅仅是展开。
  const常量有具体的类型,在编译阶段会执行类型检查。
(3) 存储方式不同
  define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。(宏定义不分配内存,变量定义分配内存。)
  const常量会在内存中分配(可以是堆中也可以是栈中)。
  (4)const 可以节省空间,避免不必要的内存分配。 例如:
#define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ……
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝(因为是全局的只读变量,存在静态区),而 #define定义的常量在内存中有若干个拷贝。
(5) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
(6) 宏替换只作替换,不做计算,不做表达式求解;
宏预编译时就替换了,程序运行时,并不分配内存。
三、struct、union、class:
1, struct和union默认权限是public,class是private。
2、struct和class中的数据成员内存相互独立。Union的存储空间至少要容纳最大的数据成员。当给union中的一个数据成员赋值之后,其他数据成员的值也改变了。
3、Union不能含有引用类型的成员,不能作为基类,也不能有派生类,所以不能有虚函数。
4、struct默认继承方式为Public,class默认为private。
5、struct和union不能使用模版定义变量。class可以。
四:引用、指针的区别:
1。引用是变量的别名,不占用内存。指针是一个变量,指向变量的地址,占用内存。
2。引用创建时必须初始化,指针不用(但是注意,没有初始化的指针是不能用的。)
3、一旦引用初始化后,就不能改变引用所指向的变量; 指针可以改变指向别的对象
4、指针可以有多级,但是引用只能是一级
5。指针自增和引用的表示意义不一样。
6.不能建立数组的引用,但是可以有数组的指针。
7、不能返回局部变量的引用。不能返回函数内部new分配的内存的引用。
四、指针和数组的区别:
1。指针可以在任何区域创建,数组只能在自由区(栈)或者静态区(全局变量)
2。作为函数参数时,数组退化为指针。
3。sizeof()得到的结果可能不同。
五: int (*s[10])(int) 表示的是什么?
int (*s[10])(int) 函数指针数组,每个指针指向一个int func(int param)的函数。
六:重载、覆盖、隐藏:
1。重载(overload):同类同函数名不同参
2。覆盖(override):覆盖有时也被叫做重写?不同类(父类和子类)同函数名同参
3。隐藏:不同类同名同参(父类没有virtual),隐藏父类函数。
不同类同名不同参,隐藏父类函数

class Base{
public:
virtual void fun();};

class A{
public:
/*隐藏父类的fun(),同名不同参,此时有两个名为fun函数,一个是继承自Base的fun(),一个是类A的fun(int a)*/
void fun(int a)

}

class B:public  A
{
void fun(int a)//隐藏类A的fun(int a),同名同参父类无virtual
}

七、多继承与多重继承
多继承:一个子类继承多个父类
多重继承:类A派生B,类B派生类C,这就称为多重继承。
虚继承是为了防止多重继承过程中产生数据冗余。
类中有虚函数表,通过指针调用虚函数。派生类会生成一个兼容基类的虚函数表。对象有虚函数指针(没有虚函数表)

八、深拷贝和浅拷贝:

浅拷贝:只进行简单的值拷贝。如果类内有指针类型的数据成员,在调用拷贝构造函数的时候,他们指向的是同一块内存。这就会出现问题。在调用析构函数的时候,会对同一块内存释放两次。
深拷贝:调用拷贝构造函数的时候,指针类型的数据成员指向不同的内存地址,在写拷贝构造函数的时候,指针要重新申请一块内存来拷贝数据。
例如:

class A
{public:
     A()
     {m_iAt=5;
     m_pA=new int[m_iA]
     }
     A(const A&a)
     {m_iA=a.m_ia;
     m_pA=new int[m_iA];
     for(int i=0;i<m_iA;i++)
     {m_pA[i]=a.m_pA[i];}

     }
private:
int m_iA;
int *m_pA;
     }

八:sizeof和strlen:
sizeof是指的存储能力。例如,char s[10]=“hello”,sizeof(s) =10。
strlen指的是当前存储了多少。对于数组s。strlen(s)=5.
sizeof是运算符,可以用类型做参数。具体而言,当参数分别如下时,sizeof返回的值表示的含义如下:
数组——编译时分配的数组空间大小;
指针——存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为4);
类型——该类型所占的空间大小;
对象——对象的实际占用空间大小;
函数——函数的返回类型所占的空间大小。函数的返回类型不能是void。
strlen是函数,参数只能是char *。


同时还应注意区分vector容器的size()和capacity()的区别。


九:inline内联函数:
inline关键字必须和函数体定义放在一起才可以实现内联,仅仅将inline放在函数声明之前不起任何作用。inline是一个用于实现的关键字而不是一个用于声明的关键字。对于类方法,定义在类体内部的方法自动成为内联方法。
内联函数是通过代码膨胀来执行的,在内联函数调用处复制函数代码,这样省去了普通函数调用的时空开销,提高了程序执行效率,但是由于代码复制增加了内存开销,所以内联函数应当是小函数、执行耗时短的函数。
十:线程和进程:

定义方面:进程是程序在某个数据集合上的一次运行活动;线程是进程中的一个执行路径。
角色方面:在支持线程机制的系统中,进程是系统资源分配的单位,线程是系统调度的单位。
资源共享方面:进程之间不能共享资源,而线程共享所在进程的地址空间和其它资源。同时线程还有自己的栈和栈指针,程序计数器等寄存器。
独立性方面:进程有自己独立的地址空间,而线程没有,线程必须依赖于进程而存在。
十一:is-a和has-a
is-a:继承
has-a:类中的数据成员是另一个类的实例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值