virtual void f()=0;
是接口,子类必须要实现
如果一个类含有至少一个纯虚函数,这个类称为抽象类(abstract class).
抽象类不能实例化
数组:数据顺序存储,固定大小
链表:数据可以随机存储,大小可动态改变
3. 已知一个数组table,用一个宏定义,求出数据的元素个数
#define NTBL (sizeof(table)/sizeof(table[0]))
4. violate的三个作用
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。
假设被面试者正确地回答了这些问题,我将稍微深究一下,看一下这家伙是不是真正懂得volatile的重要性。
1). 一个参数既可以是const还可以是volatile吗?解释为什么。
2). 一个指针可以是volatile 吗?解释为什么。
3). 下面的函数有什么错误:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
下面是答案:
1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2). 是的。尽管这并不很常见。一个例子是当一个中断服务子程序中一个指向buffer的指针。
3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
5. 对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
答:c用宏定义,c++用inline
6. 常引用
引用就是一个别名(alias),引用本身不占用存储单元。数组不能引用。
如果既要提高效率,又要保证不在函数内被改变值,应该用常引用
例1,
int a ;
const int &ra=a;
ra=1; //错误
a=1; //正确
例2,
void bar(string &s);
string foo();
bar(foo()); //错,试图将const转为非const
bar("hello");//错,试图将const转为非const
correction:
void bar(conststring &s);
7. c++是不是类型安全的?
不是。任意两个类型之间可以用reinterpret_cast来转换
8. main函数执行之前,还会执行其他代码吗?
会执行全局对象的构造函数
9. sizeof一个空类是多少?即没有成员函数与成员变量
答案为1,是编译器强制加入的
10. 什么函数不能声明为虚函数?
构造函数
11. 什么是预编译?何时需要预编译?
预编译处理文本的替代工作,如1)宏定义,2)条件编译,3)文件包含
12. list与vector的区别?
list内部使用链表,访问速度慢,但是删除快
vector内部使用数组,访问速度快,但是删除慢
13. 抽象类为什么不能实例化?
抽象类内部的纯虚函数没有具体的实现,所以不能实例化
14. 函数后面加const怎么理解?
函数后面加const表示该函数不会修改类中各成员变量的值,编译器如果发现某个const函数修改了类成员变量的值就会报错
struct A {int i;
void set(int v) {i = v;} //不能加const,因为i值改变了。
int value() const {return i;} //正确,i值没有改变。
int value2() const {return i++;} //错误,因为i值改变了。必须将const去掉。
};
如果函数比较复杂时,比如并不直接改变某个值,但是调用了其它函数,编译器怎么判断函数是否const呢。可以看下面的例子。
struct B {
A a; //B里包含一个A类成员。
int func1() const {return a.value();} //正确,所调用的a.value()也是一个const函数。
int func2() const {return a.value2();} //错误,a.value2()不是const函数(a.value2的const去掉)。
};
15. 编写strcat
char *strcat (char *dst, const char *src)
{
assert((dst!=NULL)&&(src!=NULL));
char *cp = dst;
while (*cp) cp++;
while (*cp++ = *src++);
return dst;
}