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

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

  1. .参数是值传递,函数给参数p重新开辟空间,所以改变的是p指向的空间,str没变。
  2. GetMemory函数执行完成后,str仍然指向NULL,所以赋值时回奔溃 。
  3. 正确的做法应该使用双指针 。
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

友元关系是单向的,不是对称,不能传递。
关于传递性,有人比喻:父亲的朋友不一定是儿子的朋友。
那关于对称性,是不是:他把她当朋友,她却不把他当朋友,(●ˇ∀ˇ●)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值