您的位置:首页 > 编程语言 > C语言/C++

C/C++知识点整理(3)

2016-03-27 22:38 344 查看
1. C++中构造函数和析构函数可以抛出异常吗?

A.都不行

B.都可以

C.只有构造函数可以

D.只有析构函数可以

答案:C

构造函数尽量不抛异常,析构函数不要抛异常。

对于构造函数:

在构造函数中抛出异常,将导致正在构造的对象的析构函数不会被执行。当对象发生部分构造时,已经构造完成的子对象将被逆序的析构(即异常发生点前面的对象),而还没有开始构造的子对象将不会被构造了(即异常发生点后面的对象),但正在构造的子对象和对象自己本身将停止构建,并且它的析构函数树不会被调用的。

对于析构函数:

more effective c++提出两点理由(析构函数不能抛出异常的理由):

(1)如果析构函数抛出异常,则异常点之后的程序不会执行,如果析构函数在异常点之后执行了某些必要动作,比如释放某些资源,则这些动作不会被执行,会造成诸如资源泄露的问题。

(2)通常异常发生时,C++的机制会调用已经构造对象的析构函数来释放资源,此时若析构函数本身也抛出异常,则前一个异常未处理,又出现新的异常会导致程序崩溃。

解决方案:

如果某个操作可能会抛出异常,class应该提供一个普通函数而非析构函数,来执行该操作。

如果无法保证在析构函数不发生异常。我们可以用try catch来将异常吞下。也就是把异常完全封装在析构函数内部,绝不让异常抛出函数之外。

~ClassName()
{
try{
do_something();
}
catch(){
//可以什么都不做,只是保证catch块的程序抛出的异常不会被扔出析构函数之外
}
}


2. 下面四个类A,B,C,D,在32位机器上sizeof(A),sizeof(B),sizeof(C),sizeof(D)值分别为()

class A{
};
class B{
char ch;
int x;
};
class C{
public:
void Print(void){}
};
class D
{
public:
virtual void Print(void){}
};


答案: 1,8,1,4

类A空类型的实例虽然不包含任何信息,但是必须在内存中占一定的空间,否则无法使用这些实例,一般都是1。

类B因为内存对齐所以为8。

类C里面虽然有函数,但是只需要知道函数的地址即可,而这些函数的地址只与类型相关,而

与类型的实例无关,编译器不会因为函数而在内存中多添加任何的额外信息.所以还是1 。

类D因为有虚函数,C++的编译器一旦发现一个类型中有虚函数,就会为该类型生成虚函数表,并在该类型的

每一个实例中添加一个指向虚函数表的指针.因为多了一个指针,所以在32位机器为4,64位机器为8。

3. 假定CSomething是一个类,执行下面这些语句之后,内存里创建了__个CSomething对象。

CSomething a();
CSomething b(2);
CSomething c[3];
CSomething &ra = b;
CSomething d=b;
CSomething *pA = c;
CSomething *p = new CSomething(4);


答案:6

CSomething a();// 没有创建对象,这里不是使用默认构造函数,而是定义了一个函数,在C++ Primer393页中有说明。定义一个函数,参数为空,返回值为CSomething对象, 类似int func() 。

CSomething b(2);//使用一个参数的构造函数,创建了一个对象。

CSomething c[3];//使用无参构造函数,创建了3个对象。

CSomething &ra=b;//ra引用b,没有创建新对象。

CSomething d=b;//使用拷贝构造函数,创建了一个新的对象d。

CSomething *pA = c;//创建指针,指向对象c,没有构造新对象。

CSomething *p = new CSomething(4);//新建一个对象。

4. 有以下程序

#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
int m=0123, n = 123;
printf("%o %o\n", m, n);
return 0;
}


程序运行后的输出结果是()

A.0123 0173

B.0123 173

C.123 173

D.173 173

答案: C

o% 表示8进制进行输出int m=0123; m已经是8进制不需要进行转换 而n=123是10进制 需要进行8进制转换 得173 。

5. 关于虚函数的描述正确的是()

A.派生类的虚函数与基类的虚函数具有不同的参数个数和类型

B.内联函数不能是虚函数

C.派生类必须重新定义基类的虚函数

D.虚函数可以是一个static型的函数

答案:B

内联函数是编译器就展开的,把代码镶嵌就程序,虚函数是动态绑定,运行期决定的。所以内联函数不能是虚函数 。

6. 有以下程序

#include <stdio. h>
int fun( intA )
{
int b = 0;
static int c = 3;
a = ( c + +,b + + );
return ( a );
}
main( )
{
int a = 2,i,k;
for( i = 0;i<2;i + + )
k = fun( a + + );
printf("%d\n",k );
}


程序的输出结果是?

答案:0

这个题目考的是逗号表达式,a = 表达式1,表达式2,则a = 表达式2,同理如果后面有n个表达式的话,返回的是最后一个表达式的值。

7. 有如下程序段:

#include <iostream>

void GetMemeory(char *p)
{
p = (char *)malloc(100);
}
void Test()
{
char *str = NULL;
GetMemeory(str);
strcpy(str, "Thunder");
strcat(str + 2, "Downloader");
printf(str);
}


请问运行Test函数结果是:

A.Thunder Downloader

B.under Downloader

C.Thunderownloader

D.程序崩溃

答案:D

.参数是值传递,函数给参数p重新开辟空间,所以改变的是p指向的空间,str没变。

GetMemory函数执行完成后,str仍然指向NULL,所以赋值时回奔溃 。

正确的做法应该使用双指针 。

void GetMemory(char **p){
*p = (char *)malloc(100);
}
void Test(){
char *str = NULL;
GetMemory(&str);
printf(str);
}


8. 不能作为重载函数的调用的依据是:

A.参数个数

B.参数类型

C.函数类型

D.函数名称

答案:C

9.以下代码编译有错误,哪个选项能解决编译错误?

class A {
public:
int GetValue() const {
vv = 1;
return vv;
}
private:
int vv;
};


A.改变成员变量”vv”为”mutable int vv”

B.改变成员函数”GetValue”的声明,以使其不是const的

C.都不能修复编译错误

D.都可以修复编译错误

答案:D

mutalbe的中文意思是“可变的,易变的”,跟constant(既 C ++中的const)是反义词。

在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。

我们知道,如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成const的。但是,有些时候,我们需要在const的函数里面修改一些跟类状态无关的数据成员,那么这个数据成员就应该被mutalbe来修饰。

10.有一个类B继承自类A,他们数据成员如下:

class A {
...
private:
int &a;
};
class B : public A {
...
private:
int a;
public:
const int b;
A c;
static const char* d;
A* e;
};


则构造函数中,成员变量一定要通过初始化列表来初始化的是__。

答案:b,c

在构造函数中需要初始化列表初始化的有如下三种情况 :

1.带有const修饰的类成员 ,如const int a ;

2.引用成员数据,如 int& p;

3.带有引用的类变量

static成员是不允许在类内初始化的,除了const,那么static const 成员是不是在初始化列表中呢?

当然不是。

一是static属于类,它在未实例化的时候就已经存在了,而构造函数的初始化列表嘞,只有在实例化的时候才执行。

其二是static成员不属于对象。我们在调用构造函数是创建对象,一个跟对象没直接关系的成员要它做什么呢 o(^▽^)o。

11. 类A是类B的友元,类C是类A的公有派生类,忽略特殊情况则下列说法正确的是()

A.类B是类A的友元

B.类C不是类B的友元

C.类C是类B的友元

D.类B不是类A的友元

答案:B,D

友元关系是单向的,不是对称,不能传递。

关于传递性,有人比喻:父亲的朋友不一定是儿子的朋友。

那关于对称性,是不是:他把她当朋友,她却不把他当朋友,(●ˇ∀ˇ●)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++面试笔试