day 02

1、以下标识符中不全是保留字的是
A case for int

B default then while

C bool class long

D goto return char

答案: B

解释:首先说明一下保留字的概念:指在高级语言中已经定义过的字使用者不能再将这些字作为变量名或者过程名使用。

如下代码:

int main ()
{
    int default = 2;
    int then =1;
    cout <<default <<then <<endl;
    system("PAUSE");
    return 0;   
}   

是可以正常进行运行的。

2、下面这段代码中,执行之后i和j的值是?

int i = 1;
int j = ;
j = i++;

 结果是:i = 2, j = 1;

3、派生类的成员函数可以直接访问基类的公有成员和保护成员。

A 是  B 否

答案: A

解析:

  1、《C++ Primer》544页有说明,“派生访问说明符对于派生类的成员(及友元)能否访问其直接基类的成员没什么影响。对基类成员的访问权限只与基类中的访问说明符有关。”“派生类访问说明符的目的是控制派生类用户对于基类成员的访问权限。”

可见,即使是private继承,派生类成员也是可以访问基类的public和protected成员的,只是这些成员在派生类里都为private性质的(就好像普通的类成员可以访问自己类里的私有成员一样),而派生类构造的对象不能访问(就好像在类外访问类中的私有成员)。

  2、无论是任何继承方式,基类的直接派生类的普通成员函数都是可以直接访问基类的普通成员变量。

(除静态成员函数,因为静态成员函数在程序刚开始进行的时候就存在了,在没有类进行实例化的之前就存在了,所以当然没办法访问在实例化对象之后才能生成的普通成员变量,只能访问同一生命期(都是在程序刚开始时生成的)的静态成员变量了。

而且静态成员函数不仅仅是不能访问直接基类的静态成员变量,所有层级的父类和本类的非静态成员变量都不能直接访问,原因还是生命期的问题)

4、在多文件结构的程序中,通常把类的定义单独存放于()中;

A 源文件  B 主文件   C 库文件  D  头文件

答案: D

解析:
头文件中叫类的定义;源文件中叫类的实现;

一般情况下,类的定义和函数声明在头文件中,类的实现和函数定义在源文件中。

5、以下说法正确的是()

A 用户调用标准库函数之前,必须重新定义。

B 若已包含标准库头文件及相关命名空间,用户也可以重新定义标准库函数,但是该函数将失去原有含义。

C 若已包含标准库头文件及相关命名空间,则系统不允许用户重新定义标准库函数。

D 用户调用标准库函数前,不必使用预编译命令将该函数所在文件包括到用户源文件中。

答案:C

解析:

  A选项,函数不能重新定义,只能重载,除非换作用域(那也不能叫重新定义); B选项,函数可以被重载而不能重新定义,重载后函数具有不同的形参,原有定义并不失效; C选项,正确; D选项,调用库函数果断需要#include(预处理包含)头文件啊……否则找不到函数定义…… 网上看到的解析

  重新定义说明其函数名以及参数列表和标准库函数一致,在编译时若调用标准库头文件,则会报重复定义的错误;但重载该函数是可以的

6、以下代码是否完全的正确,执行可能得到的结果是()

class A{
	int i;
};

class B {
	A *p;
	public :
	B(){p = new A; }
	~B(){delete p;}
};
void sayHello(B b)
{
	
}
int main (){
	B b;
	sayHello(b);
}

 

答案是: 程序崩溃;

解析:

  1、为了清晰可见,我们从新把题目代码码一遍:

class A{
   int i;
};
class B{
   A *p;
public:
   B(){p=new A;}
   ~B(){delete p;}
   /*
   B(const B& ths){
    p = ths.p;
   }*/
};
void sayHello(B x){
}
int main(){
   B b;
   sayHello(b);
}

 
  这里的错误原因是编译器在生成default copy construction的时候使用的bitwise copy语义,也就是只是简单的浅拷贝。 上面被注释掉的程序就是编译器自动添加的部分。 从而导致在sayHello中向参数x传递值时,调用了bitwise copy的拷贝构造函数,使得x对象和b对象中的值完全一致,包括p指针的值,在x离开作用域(也就是sayHello函数结束),x发生析构,调用delete 销毁了指针p,同时在main函数结束的时候,析构b时又会调用一次delete删除指针p。
也就是本程序会delete一直已经被delete 的指针。可以做如下改进,来修复程序:

class A{
   int i;
};
class B{
   A *p;
public:
   B(){p=new A;}
   ~B(){delete p;}
   B(const B& other){
    p = new A;  //构建新的指针
    *p = *(other.p); //将指向的内容复制,依然指向不同的位置
   }
};
void sayHello(B b){
}
int main(){
   B b;
   sayHello(b);
}

如上,在B中添加copy 构造函数

  2、

  在传递参数的时候调用了一次拷贝构造函数,在离开函数时调用了一个析构函数,因为默认的拷贝构造函数只是简单的赋值,所以拷贝后两个对象中的p还是指向同一块内存,在离开main函数作用域后由调用一次析构函数,同一个指针,两次delete运行肯定会出错

  3、

  当用一个对象来初始化另一个对象是会使用拷贝函数,这里用A来初始化B,需要拷贝构造函数,但是本题没有显示拷贝函数,那么就会调用默认的拷贝函数,由于类中含有指针,所以需要手动写一个拷贝构造函数,称之为深拷贝。

   拷贝构造函数 :http://blog.csdn.net/lwbeyond/article/details/6202256

posted @ 2019-06-30 08:55  Mr_Song_D  阅读(238)  评论(0编辑  收藏  举报