目录
第一题(不能被重载的运算符)
下列运算符中,在C++语言中不能重载的是:
A *
B >=
C ::
D delete
1.类当中的成员我们是通过 . 来访问的,这个 . 是不能被重载的
2.这个 .* 也就是总和也是不能被重载的
3.作用域运算符::也是不能被重载的
4.三目元算符 ?:也是不能被重载的
5.sizeof也是不能被重载的
C
第二题(拷贝构造的问题)
拷贝构造函数的特点是()
A 该函数名同类名,也是一种构造函数,该函数返回自身引用
B 该函数只有一个参数,是对某个对象的引用
C 每个类都必须有一个拷贝初始化构造函数,如果类中没有说明拷贝构造函数,则编译器系统会自动生成一个缺省拷贝构造函数,作为该类的保护成员
D 拷贝初始化构造函数的作用是将一个已知对象的数据成员值拷贝给正在创建的另一个同类的对象
class A
A(A&)或者 A(const A&a)
A a1;
A a2(a2);//调用拷贝构造函数
A:构造函数是没有返回值的,在构造函数的前面不可以给出返回值的类型
B:是对本类类型的引用,不是某个对象
C:作为该类的不是保护成员函数,而是共有成员函数
D
第三题(函数定义中const的位置)
print()函数是一个类的常成员函数,它无返回值,下列表示中正确的是()
A const void print();
B void const print();
C void print() const;
D void print(const);
没有返回值,所以最左边一定是void,const类型的成员函数就是在该函数的参数列表后面加上const就可以了,
如果是在print后面的()里面的,也就是修饰参数列表中的参数,就是将参数变成const属性
如果是在返回值的位置,那么就是代表着返回值是const属性的,是不能被修改的
所以我们这道题的const位置应该在参数列表之后。
注意:此处的const实际修饰的是this指针,表名在该函数成员中,不能修改非静态的成员变量!
C
第四题(构造函数执行的次数)
如果MyClass为一个类,执行”MyClass a[5], *b[6]”语言会自动调用该类构造函数的次数是()
A 2
B 5
C 4
D 9
MyClass a[5]:是5个MyClass对象的一个数组,调用5次Myclass类的构造函数
*b[6]:b实际为一个指针数组,该数组中的每个元素都是一个MyClass*,并不会调用构造函数!
B
第五题(初始化列表中初始化成员的次序)
下面的程序输出可能是什么?
class Printer{
public:
Printer(std::string name) {std::cout << name;}
};
class Container{
public:
Container() : b("b"), a("a") {}
Printer a;
Printer b;
};
int main(){
Container c;
return 0;
}
A 可能是 "ab" 或 "ba"。 依赖于具体的实现
B 一直都是 "ba"
C 一直都是 "ab"
这里我们的Containter再构造的时候,会调用初始化列表中的b("b"),a("a"),也就是构造b和a两个对象。
在初始化列表中初始化成员的次序:与该成员在初始化列表中出现的先后次序没有关系,真正的初始化的次序与成员变量在类中的生成的先后次序保持一致。
我们看到下面的
Printer a;
Printer b;
也就是先初始化a,再初始化b,然后调用a和b的构造函数的时候,就是会先打印出a,然后再打印b
注意:成员初始化的顺序和你在初始化列表中的先后顺序无关
C
第六题(空类的大小)
在Windows 32位操作系统中,假设字节对齐为4,对于一个空的类A,sizeof(A)的值为()?
A 0
B 1
C 2
D 4
类大小的计算方式:将类中非静态成员变量大小相加,注意内存对齐--和成员函数没有关系,与结构体大小的计算方式类似
注意:孔磊大小并不是0,在主流编译器中,将空类的大小设置为1
假设这个空类的大小为0:A a1,a2,a3;
那么在这三个对象创建期间,就必须为这三个对象分配内存a1,a2,a3。
那如果空类的大小为0,那么a1在它的地址但是不占用任何空间,那么a2也是在a1的位置进行创建的,因为a2的大小同样也是0,那么0+0还是0,所以a2还在a1的位置,所以编译器根本就没办法分别是a1还是a2,所以主流的编译器都会将空类的大小设置为1
注意:不是所有的编译器都是将空类的大小设置为1的!(主流的VS和linux下的编译器是这样的)
B
第七题(const修饰问题)
以下程序输出是____。
#include <iostream>
using namespace std;
int main(void)
{
const int a = 10;
int * p = (int *)(&a);
*p = 20;
cout<<"a = "<<a<<", *p = "<<*p<<endl;
return 0;
}
A 编译阶段报错运行阶段报错
B a = 10, *p = 10
C a = 20, *p = 20
D a = 10, *p = 20
E a = 20, *p = 10
&a的类型:const int *也就是a当中的值不能被修改
int *p=(int *)(&a)需要将a强转成int*类型,我们的代码才能通过这一行的编译
*p=20也就是将p所指向的空间的数值变成20。虽然说a是一个常量,不能通过a来改变自己,但是可以通过指针类修改a所在的空间中的内容。
所以我们的a=20,那么我们的*p=20吗?
不!这个题考察的是c++中被const修饰的变量:该变量已经是一个常量了,还具有替换的作用。编译器在编译代码期间,在程序中看到对常量中内容读取时,会直接使用常量中的内容替换该常量。
a定义好之后,在读取的时候会被替换为原先的值10,但是a的本身的值其实已经是20了,也就是还在cout<<a的时候就会打印出10,而不是20!所以我们*p依旧是20。
修改的时候是要把a的值复制到内存进行修改,*p取得是内存数据,打印a是要在常量区取a的值
D