some C++ summary 2

来源:互联网 发布:动感单车品牌知乎 编辑:程序博客网 时间:2024/05/16 14:54
1. 纯虚函数如何定义?使用时应注意什么?抽象类是如何定义的?抽象类能否实例化?
virtual void f()=0;

是接口,子类必须要实现

如果一个类含有至少一个纯虚函数,这个类称为抽象类(abstract class).

抽象类不能实例化



2.数组和链表的区别
数组:数据顺序存储,固定大小

链表:数据可以随机存储,大小可动态改变


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;

}