一. 单选
1. 下面叙述不正确的是()
A 派生类一般都用公有派生
B 对基类成员的访问必须是无二义性的
C 赋值兼容规则也适用于多重继承的组合
D 父类的公有成员在派生类中仍然是公有的
D.会依赖于派生类的继承方式class A { public: void func() { cout<<"A"<<endl; } }; //class B:private A //此时A类的公有成员到B类变成私有 class B:public A //此时才是公有 { public: void func() { cout<<"B"<<endl; } };
2. 下面 C++ 程序的运行结果是()
#include <iostream>
using namespace std;
class parent {
int i;
protected:
int x;
public:
parent() { x = 0; i = 0; }
void change() { x++; i++; }
void display();
};
class son :public parent {
public:
void modify();
};
void parent::display() {
cout << "x=" << x << endl;
}
void son::modify() {
x++;
}
int main() {
son A;
parent B;
A.display();
A.change();
A.modify();
A.display();
B.change();
B.display();
return 0;
}
A x=1
x=0
x=2
B x=2
x=0
x=1
C x=0
x=2
x=1
D x=0
x=1
x=2
注意此题的A B是两个不同的对象son中没有display()这个函数,所以去parent类中查找,先调用parent类的无参构造函数
3. 关于虚函数的描述正确的是()
A 派生类的虚函数与基类的虚函数具有不同的参数个数和类型
B 内联函数不能是虚函数
C 派生类必须重新定义基类的虚函数
D 虚函数可以是一个static型的函数
A. 若要使用多态,派生类必须重写基类的虚函数重写:函数返回值类型,函数名,参数列表完全一致B. inline只是一个建议,如果内联函数中的程序中含有循环,递归等繁琐代码时,编译器会自动优化C. 派生类必须 重写基类的虚函数D. 虚函数不能是静态成员函数.因为静态函数没有this指针,而调用虚函数要靠this指针调用对象的信息调用此虚表
4. 当一个类对象的生命周期结束后,关于调用析构函数的描述正确的是()
A 如果派生类没有定义析构函数,则只调用基类的析构函数
B 如果基类没有定义析构函数,则只调用派生类的析构函数
C 先调用派生类的析构函数,后调用基类的析构函数
D 先调用基类的析构函数,后调用派生类的析构函数
析构函数:先调用的后析构,后调用的析构一个类对象的执行过程是先调用基类的构造函数,再调用派生类的构造函数
5. 以下关于纯虚函数的说法,正确的是()
A 声明纯虚函数的类不能实例化
B 声明纯虚函数的类成虚基类
C 子类必须实现基类的纯虚函数
D 纯虚函数必须是空函数
A B 当类中有了纯虚函数,这个类也称为抽象类抽象类无法实例化对象(只能作为其他类的基类)C 子类必须重写抽象类中的纯虚函数,否则也属于抽象类D 纯虚函数:virtual 返回值类型 函数名(参数列表)=0;
6. 下列描述,正确的一共有多少个()
1)const char *p,这是一个常量指针,p的值不可修改
2)在64位机上,char *p= “abcdefghijk”; sizeof(p)大小为12
3)inline会检查函数参数,所以调用开销显著大于宏
4)重载是编译时确定的,虚函数是运行时绑定的
A 1
B 2
C 3
D 4
1) const char *p;//const 封锁的是*p,是常量,所以p的指向是可以修改的,但是p所指的空间的值不能改变.2)在32位机上,一个指针大小为4,在64位机上,一个指针大小为8,它的大小只和它的类型有关,而p是一个指针3) inline在调用时也会进行展开,所以调用开销和宏差不多
7. C++将父类的析构函数定义为虚函数,下列正确的是哪个()
A 释放父类指针时能正确释放子类对象
B 释放子类指针时能正确释放父类对象
C 这样做是错误的
D 以上全错
new一个父类对象,对父类对象进行初始化delete时,会调用析构函数进行清理工作
8. 下列关于多态性说法不正确的是()
A 多态性是指同名函数对应多种不同的实现
B 重载方式仅有函数重载
C 重载方式包含函数重载和运算符重载
D 多态性表现为静态和动态两种方式
重载的方式包括函数重载还有运算符重载
9. 分析一下这段程序的输出
#include<iostream>
using namespace std;
class B
{
public:
B()
{
cout << "default constructor" << " ";
}
~B()
{
cout << "destructed" << " ";
}
B(int i): data(i)
{
cout << "constructed by parameter" << data << " ";
}
private:
int data;
};
B Play( B b)
{
return b;
}
int main(int argc, char *argv[])
{
B temp = Play(5);
return 0;
}
A constructed by parameter5 destructed destructed
B constructed by parameter5 destructed
C default constructor" constructed by parameter5 destructed
D default constructor" constructed by parameter5 destructed destructed
B temp = Play(5);//带参,会先去调用B类的带参构造函数,然后return b;返回对象时编译器进行优化,这里调用了2次析构函数
10. 求输出结果
#include <iostream>
using namespace std;
class A
{
public:
virtual void print()
{
cout << "A::print()" << "\n";
}
};
class B: public A
{
public:
virtual void print()
{
cout << "B::print()" << "\n";
}
};
class C: public A
{
public:
virtual void print()
{
cout << "C::print()" << "\n";
}
};
void print(A a)
{
a.print();
}
int main()
{
A a, *aa, *ab, *ac;
B b;
C c;
aa = &a;
ab = &b;
ac = &c;
a.print();
b.print();
c.print();
aa->print();
ab->print();
ac->print();
print(a);
print(b);
print(c);
}
A C::print() B::print() A::print() A::print() B::print() C::print() A::print() A::print() A::print()
B A::print() B::print() C::print() A::print() B::print() C::print() A::print() A::print() A::print()
C A::print() B::print() C::print() A::print() B::print() C::print() B::print() B::print() B::print()
D C::print() B::print() A::print() A::print() B::print() C::print() C::print() C::print() C::print()
调用print(a)时,不管实参是多少,永远调用的是A类的virtual void print(){}函数