1.C++源程序文件的缺省扩展名为( A )。
A. cpp B. exe C. obj D. lik
用new运算符创建一个含10个元素的一维整型数组的正确语句是( C )。
A. int *p=new a[10]; B. int *p=new float[10];
C. int *p=new int[10]; D. int *p=new int[10]={1,2,3,4,5}
下列的符号常量定义中,错误的定义是( A )。
A、 const M=10; B、 const char ch;
C、 const int M=20; D、 const bool mark=true;
关于封装,下列说法中不正确的是( D )。
A. 通过封装,对象的全部属性和操作结合在一起,形成一个整体
B. 通过封装,一个对象的实现细节被尽可能地隐藏起来(不可见)
C. 通过封装,每个对象都成为相对独立的实体
D. 通过封装,对象的属性都是不可见的
函数重载是指( A )。
A. 两个或两个以上的函数取相同的函数名,但形参的个数或类型不同
B. 两个以上的函数取相同的名字和具有相同的参数个数,但形参的类型可以不同
C. 两个以上的函数名字不同,但形参的个数或类型相同
D. 两个以上的函数取相同的函数名,并且函数的返回类型相同
为了提高程序的运行速度,可将不太复杂的功能用函数实现,此函数应选择( D )。
A. 重载函数 B. 内联函数 C.递归函数 D.函数模板
假定AA为一个类,a为该类公有的数据成员,x为该类的一个对象,则访问x对象中数据成员a的格式为( D )。
A. x(a) B. x[a] C. x->a D. x.a
选项 C 的格式 x->a 适用于访问指针对象的成员。
一个类的构造函数通常被定义为该类的( A )成员。
A. 公有 B. 保护 C. 私有 D. 友元
类的析构函数可以带有( A )个参数。
A. 0 B. 1 C. 2 D. 任意
引入友元的主要目的是为了( A )。
A. 增强数据安全性 B. 提高程序的可靠性
C. 提高程序的效率和灵活性 D. 保证类的封装性
引入友元的主要目的是为了允许类的外部代码访问类的私有成员变量和方法,从而增强类的封装性和安全性。
引入友元可以提高程序的灵活性,但通常不会提高程序的效率。
友元虽然可以增强类的灵活性,但如果使用不当也可能会导致一个类的封装性和安全性下降。
派生类的成员函数可以直接访问基类的( B )成员。
A. 所有 B. 公有和保护 C. 保护和私有 D. 私有
在定义一个派生类时,若不使用保留字显式地规定采用何种继承方式,则默认为( D )方式。
A. 私有继承 B. 非私有继承 C. 保护继承 D. 公有继承
C++中的虚基类机制可以保证:( A )。
A. 限定基类只通过一条路径派生出派生类
B. 允许基类通过多条路径派生出派生类,派生类也就能多次继承该基类
C. 当一个类多次间接从基类派生以后,派生类对象能保留多份间接基类的成员
D. 当一个类多次间接从基类派生以后,其基类只被一次继承
虚基类是在多重继承中解决菱形继承问题的一种机制。菱形继承指的是一个派生类同时继承自两个直接或间接基类,并且这两个基类又共同继承自一个基类,导致该基类在派生类中出现了两份拷贝。为了避免这种情况,C++提供了虚基类机制,即在虚基类前加上关键字virtual,用以指示该基类为虚基类。在派生类中,每个直接或间接继承虚基类的类只保存一份虚基类的拷贝,这样就避免了派生类中出现重复的虚基类。因此,虚基类机制可以限定基类只通过一条路径派生出派生类,避免了多次继承同一虚基类的情况。
多态性是面向对象编程的一个核心概念,它允许不同的对象以各自独特的方式对同一消息(方法调用)作出响应。
在重载二元运算符时,可以将其定义为一个成员函数,其中操作数a显式地出现在函数名前面,而操作数b则作为函数参数传递。因此,在a+b的情况下,如果+运算符被定义为一个成员函数,则可以使用a.operator+(b)的格式来调用。
1、以下设置默认值的函数原型声明中错误的是( C )。
A.int add(int x, int y, int z=5); B.int add(int x, int y=4, int z=5);
C.int add(int x, int y=4, int z); D.int add(int x=3, int y=4, int z=5);
2、下列运算符中,( C )运算符在C++语言中不能重载。
A.+= B.[ ] C.:: D.new
以下的运算符不能被重载
作用域解析符(::):用于限定成员函数或变量的作用域,不能被重载。
成员指针运算符(.* 和 ->*):用于访问成员指针所指向对象的成员,不能被重载。
条件运算符(?:):用于三目运算符,不能被重载。
sizeof 运算符和 typeid 运算符:这两个运算符并不执行运算,不能被重载。
预处理器运算符 # 和 ##:这些运算符是在编译时处理预处理命令的,不能被重载。
3、系统在调用重载函数时往往根据一些条件确定哪个重载函数被调用,在下列选项中,不能作为依据的是( D )。
A.参数的个数 B.参数的类型
C.参数的顺序 D.函数的返回类型
C++ 中函数重载是指在同一个作用域内,可以有多个同名函数,它们具有不同的参数列表(包括参数个数、参数类型、参数顺序),编译器会根据这些参数列表的不同来区别它们,选择合适的函数进行调用。
4、友元的作用( B )。
A.提高程序的运行效率 B.加强类的封装性
C.实现数据的隐藏性 D.增加成员函数的种类
通过友元机制,可以在一定程度上打破类的封装性,但也可以增强其封装性。
5、模板的作用是( D )。
A.提高程序的运行效率 B.加强类的封装性
C.实现数据的隐藏性 D.提高代码可重用性
6、基类中的公有成员经过保护派生后,它在派生类中的访问属性是( B )。
A.public B.protected C.private D.不可以被继承
保护(protected)派生是一种继承方式,派生类继承了基类的公有成员和保护成员,但是不会继承基类的私有成员。
7、下列哪个不是构造函数的特征( D )。
A.构造函数名与类名同名 B.构造函数可以重载
C.构造函数可以设置默认参数 D.构造函数必须指定类型说明
8、下列关于静态数据成员的特性中,( D )是错误的。
A.说明静态数据成员时前面要加修饰符static
B.静态数据成员要在类体外进行初始化
C.可以使用类名加作用域运算符访问静态数据成员
D.静态数据成员不是该类所有对象共享的
静态数据成员是属于整个类的,它们被所有类的对象共享。在声明和定义静态数据成员时,需要在前面加上关键字 static,静态数据成员必须在类体外进行初始化,并可以使用类名和作用域解析运算符来访问。
9、关于参数缺省值的设置,正确的是( B )。
A.不允许设置参数的默认值
B.设置参数默认值只能在定义函数时设置
C.设置参数默认值时,应该先设置右边的再设置左边的
D.设置参数默认值时,应该全部参数都设置
参数缺省值可以在定义函数时进行设置,这样在调用函数时,如果不传递对应的参数,该参数会使用默认值。参数缺省值必须按照从右到左的顺序进行设置。
10、通过函数实现一种简单功能,并且需要加快执行速度,选用( A )。
A.内联函数 B.重载函数 C.递归调用 D.嵌套调用
A. 内联函数能够减少函数调用的时间开销,从而加快执行速度,并且省去了函数调用和返回时的压栈和出栈操作,可以节约内存空间。当然,在一些情况下,内联函数不一定能够优化执行速度,而且内联函数的定义必须在头文件中,容易增加代码复杂度,所以要慎重选择。但是,在这道题目中,如果我们需要加快执行速度,选用内联函数是一个合理的选择。
B. 重载函数是指在同一作用域内,有多个函数名相同但参数列表不同的函数。重载函数不能减少函数调用的时间开销,只是允许函数名相同但参数列表不同的函数共享一个函数名。因此不是最好的选择。
C. 递归调用是指在一个函数体内,直接或间接地调用函数自身。递归调用的复杂度较高,容易产生栈溢出等问题,而且在一些情况下递归调用不一定能够优化执行速度,因此不是最好的选择。
D. 嵌套调用是指在一个函数中调用其他函数,这是最普通的函数调用方式,不会减少函数调用的时间开销。因此也不是最好的选择。
11、函数的整型参数使用引用方式,为了不改变参数的内容,参数引用的格式应该是( C )。
A.const int func(int & ) B.int func(int & ) const
C.int func(const int & ) D.int func(const int * ) const
A. const int func(int &) 表示参数是一个非 const 的整型引用,这意味着在函数体内可以修改该参数所引用的值,而选项描述中又希望不改变参数的内容,所以选项 A 不正确。
B. int func(int &) const 表示参数是一个非 const 的整型引用,并且函数本身是一个常量成员函数,这意味着在函数体内不可以修改任何成员变量,而选项描述中并没有要求这个函数是一个常量成员函数,所以选项 B 不正确。
C. int func(const int &) 表示参数是一个整型常量引用,即参数的值不可以被修改。这是我们不希望修改传入参数值时最常见的方式之一。所以选项 C 正确。
D. int func(const int *) const 表示参数是一个指向整型常量的指针,而选项描述中并没有要求使用指针方式,所以选项 D 不正确。
12、关于抽象类,下列说明正确的是( C )。
A.抽象类可以创建对象 B.抽象类中只能有一个纯虚函数
C.抽象类中可以有非纯虚函数 D.抽象类不可派生出抽象类
A. 因为抽象类中存在未实现的纯虚函数,所以不能创建抽象类的对象,否则会引起编译错误。因此选项 A 不正确。
B. 抽象类中可以拥有一个或多个纯虚函数,但不是只能有一个。纯虚函数是在基类中声明的虚函数,在函数名后面加上 “= 0”。虚函数的定义由派生类完成。因此选项 B 不正确。
C. 抽象类中可以有非纯虚函数。非纯虚函数是指在抽象类中定义并给出实现的虚函数。抽象类可以有纯虚函数和非纯虚函数,派生类需要实现抽象类中所有的纯虚函数,对于非纯虚函数则不需要重新实现。因此选项 C 正确。
D. 抽象类可以被派生出抽象类。抽象类可以作为其他类的基类,派生类继承抽象类时需要实现其所有纯虚函数才能被实例化。因此选项 D 不正确。
13、下列说明中,
const char *ptr=”Nanjing”;
ptr应该是( B )。
A.指向字符常量的指针 B.指向字符的常量指针
C.指向字符串常量的指针 D.指向字符串的常量指针
指针前面的 const 关键字表示指针所指向的内容是不可修改的,可以用来修饰指针,也可以修饰指针所指向的内容。字符常量指的是一个字符,如 ‘A’、‘1’、‘\n’ 等,而字符常量指针是指向字符的指针,其所指向的内容是不可修改的。
14、多继承派生类构造函数构造对象时,最先被调用的是( B )。
A.派生类构造函数 B.虚基类的构造函数
C.非虚基类的构造函数 D.派生类子对象的构造函数
在派生类构造函数中,需要显式调用虚基类的构造函数来初始化虚基类。虚基类的构造函数会先于非虚基类和派生类子对象的构造函数被调用,以确保在初始化派生类时,虚基类的成员先被初始化,避免冲突和资源浪费。
15、下列关于对象数组的描述中,( D )是错误的。
A.对象数组的下标是从0开始的
B.对象数组的数组名是一个常量指针
C.对象数组的每个元素是同一个类的对象
D.对象数组只能赋初值,而不能在定义后赋值
A. 对象数组的下标是从0开始的,和普通数组一样。
B. 对象数组的数组名是一个常量指针,指向该数组的首地址,不能再修改。
C. 对象数组的每个元素是同一个类的对象,它们具有相同的数据类型,但可以有不同的值。
用C++风格的输入/输出流处理输入/输出时,必须包含的std名字空间中的头文件是 iostream 。
通常类的复制构造函数的参数是 const 类名 & 。
在类的定义中,除了普通数据成员、成员函数外,还可以用关键字 static 声明静态成员,静态成员函数一般专门用来访问类的 静态成员 。
若单一继承的派生类中含有对象成员,在该派生类生命周期结束时,析构函数的调用顺序是:先调用______对象成员_______的析构函数,再调用______派生类_______的析构函数,最后调用______基类_______的析构函数。
在创建对象时,系统会自动调用______构造函数_______,当对象生命周期结束时,会自动调用______析构函数_______。
C++中每个成员函数有一个特殊的隐含指针,称为______this_______指针。
1、为提高安全性,C++语言用 constexpr 来代替C中不带参的宏,用 inline 来代替带参的宏。
2、C++支持的两种多态性为 静态 多态性和 动态 多态性。
3、若单一继承的派生类中含有成员对象,在该派生类生命周期结束时,析构函数的调用顺序是,先调用 成员对象 的析构函数,再调用 派生类成员 的析构函数,最后调用 基类 析构函数。
4、 引用 是变量的别名。
5、在创建对象时,系统会自动调用 构造函数 ,当对象生命周期结束时,会自动调用 析构函数 。
1. 下面程序的输出结果是?
#include
using namespace std;
int main()
{
char *str="abbcabdced";//这句有点问题,会报错,无法从“const char [11]”转换为“char *”
int c1=0,c2=0,c3=0,c4=0;
for(int i=0;str[i];i++)
switch(str[i])
{
case 'a':c1++;break;
case 'b':c2++;break;
case 'c':c3++;break;
default:c4++;
}
cout<
输出结果为:
2,3,2,3
2. 下面程序的输出结果是?
#include
using namespace std;
class B
{
int x, y;
public:
B()
{ x = y = 0;
cout << "con1\t"; }
B(int i)
{ x = i;
y = 0;
cout << "con2\t"; }
B(int i, int j)
{ x = i;
y = j;
cout << "con3\t"; }
~B()
{ cout << "Des\t"; }
};
int main()
{
B *ptr;
ptr = new B[3];
ptr[0] = B();
ptr[1] = B(1);
ptr[2] = B(2,3);
delete[] ptr;
return 0;
}
输出结果:
con1 con1 con1 con1 Des con2 Des con3 Des Des Des Des
注意是\t(制表符),不是\n
3.下面程序的输出结果是?
#include
using namespace std;
class Circle
{
const double PI;
double r;
public:
Circle(double rr):PI(3.14)
{ r=rr; }
double Area()const
{ return PI*r*r; }
};
int main()
{
Circle c1(1);
const Circle c2(2);
cout<
输出结果:
3.14
12.56
4.下面程序的输出结果是?
#include
using namespace std;
class B
{
public:
B() { cout << "CB"; }
~B() { cout << "DB"; }
};
class D :public B
{
public:
D() { cout << "CD"; }
~D() { cout << "DD"; }
};
int main()
{
D *p = new D;
cout << "HW";
delete p;
return 0;
}
输出结果:
CBCDHWDDDB
注意cout结尾没有endl,那就不换行
5.下面程序的输出结果是?
#include
using namespace std;
class A
{
public:
virtual void fun()
{ cout<<"fun in calss A"<
fun in calss C
fun in calss C
fun in calss C
由于虚函数具有动态绑定的特性,因此程序在运行时根据实际的对象类型来决定调用哪个函数。在这个程序中,虽然三个引用都是指向同一个对象 c,但由于 C 类型重写了虚函数 fun,因此不管是哪个类型的引用调用 fun,实际上都是调用了 C 类型中重写的虚函数 fun。因此程序的输出结果都是“fun in calss C”。
1、下面程序的输出结果是?
#include
using namespace std;
void fun(int x,int &y)
{
x+=y;
y+=x;
}
int main()
{
int x=3,y=1;
fun(x,y);//x=3,y=5;
fun(y,x);//x=11,y=5;
cout<<"x="<
输出结果为:
x=11,y=5
2、下面程序的运行结果是?
#include
using namespace std;
class C
{ public:
C(){cout<<"CC";}
~C(){cout<<"DC";}
};
int main()
{ C c; cout << "HW"; return 0;}
输出结果为:
CCHWDC
注意cout后面没有endl,所以不换行
3、下面程序的运行结果是?
#include
using namespace std;
class S
{
int i;
static int k;
public:
S();
void disp();
};
S::S()
{
i=0;k++;
}
void S::disp()
{
cout<<"i="<
输出结果为:
i=0,k=2
i=0,k=2
4、分析下列程序的访问权限(省略了具体成员函数的实现)(针对具体每个回答“可以”或“不可以”)
#include
class A
{
public:
void f1( );
A(int i, int j ) { i1=i; j1=j;}
protected:
int j1;
private:
int i1;
};
class B : protected A
{
public:
void f2( );
B(int i,int j, int k ,int l):A(i, j) { i2=k; j2=l;}
protected:
int j2;
private:
int i2;
};
(1) 派生类B中成员函数f2()能否访问基类A中的成员f1( )、i1和j1?能否访问B中的成员j2和i2?
(2) 派生类B的对象b能否访问基类A中的成员f1( )、i1和j1?能否访问B中的成员j2和i2?
(1)答:不可以,可以
(2)答:不可以,不可以
派生类 B 中的成员函数 f2() 能否访问基类 A 中的成员 f1()、i1 和 j1?
不可以。因为 B 类继承了 A 类并采用了 protected 继承方式,基类 A 中的成员在派生类 B 中的访问权限是保护的,只能在派生类 B 的成员函数和它的派生类中被访问,不能被类外部的函数、对象直接访问。因此,派生类 B 中的成员函数 f2() 只能访问派生类 B 和基类 A 中的保护成员变量 j1 和 j2,而不能访问基类 A 中的成员 f1() 和私有成员变量 i1。
.
派生类 B 中的成员函数 f2() 能否访问 B 中的成员 j2 和 i2?
可以。派生类 B 中的成员函数 f2() 能够访问 B 类中的所有成员变量,包括公共的、保护的和私有的成员变量。
.
派生类 B 的对象 b 能否访问基类 A 中的成员 f1()、i1 和 j1?
不可以。因为类 B 的继承方式是 protected 继承,派生类的对象所包含的基类成员,对该对象的使用者没有意义,因此不能访问基类 A 中的成员 f1() 和 i1。只有在类 B 的成员函数和派生类中才能访问基类 A 中的保护成员变量 j1。
.
派生类 B 的对象 b 能否访问 B 中的成员 j2 和 i2?
不可以。因为在派生类 B 中,成员变量 j2 和 i2 的访问权限是保护的,只能在派生类 B 和它的派生类中被访问,不能被类外部的函数、对象直接访问。而派生类 B 的对象 b 只是该类的一个实例,不能直接访问它的成员变量 j2 和 i2,只能通过派生类的成员函数进行访问。
5、下面程序的运行结果是?
#include
using namespace std;
class B
{ public:
B(){cout<<"CB";}
~B(){cout<<"DB";}
};
class D:public B
{
public:
D(){cout<<"CD";}
~D(){cout<<"DD";}
};
int main()
{ D *p=new D; cout<<"HW"; delete p; return 0;}
运行结果为:
CBCDHWDDDB
1.定义一个时间类Time,有3个私有成员变量Hour,Minute,Second,定义构造函数、析构函数以及用于改变、获取、输出时间信息的公有函数,主函数中定义时间对象,并通过调用各种成员函数完成时间的设定、改变、获取、输出等功能。
//巨完整版
#include
using namespace std;
class Time {
private:
int Hour, Minute, Second;
public:
Time() {};
Time(int h, int m, int s) {
Hour = h;
Minute = m;
Second = s;
}
void Set(int h, int m, int s) {
Hour = h;
Minute = m;
Second = s;
}
void SetHour(int h) {
Hour = h;
}
int GetHour() {
return Hour;
}
void SetMinute(int m) {
Minute = m;
}
int GetMinute() {
return Minute;
}
void SetSecond(int s) {
Second = s;
}
int GetSecond() {
return Second;
}
void Print() {
cout << "Time is " << Hour << " : " << Minute << " : " << Second << endl;
}
~Time() {
cout << "Time is " << Hour << " : " << Minute << " : " << Second << endl;
cout << "class Time is over"<
2.定义Point类,在该类中包含如下内容:
1)私有数据成员:
double x; //x轴坐标
double y; //y轴坐标
2)公有成员函数:
构造函数 //默认值为原点(0.0,0.0)
void Print(); // 输出坐标点
Point operator++(); //成员函数重载前置“++”
Point operator-(const Point &a); //成员函数重载运算符“-”
friend Point operator+(const Point &a,const Point &b); //友元函数重载“+”
要求:实现Point类的定义以及成员函数的实现,并在主函数中定义对象进行测试。
#include
using namespace std;
class Point {
private:
double x;
double y;
public:
Point() {
x = 0.0; y = 0.0;
}
Point(int xx, int yy) {
x = xx;
y = yy;
}
void Print() {
cout << "Point = (" << x << "," << y << ")";
}
Point operator++();
Point operator-(const Point& a);
friend Point operator+(const Point& a, const Point& b);
};
Point Point::operator++() {
x++; y++;
return *this;
}
Point Point::operator-(const Point& a) {
Point res;
res.x = x - a.x;
res.y = y - a.y;
return res;
}
Point operator+(const Point& a, const Point& b) {
Point res;
res.x = b.x + a.x;
res.y = b.y + a.y;
return res;
}
int main() {
Point p1(1.0, 2.0);
Point p2(3.0, 4.0);
Point p3 = p1 + p2;
p3.Print();
++p3;
p3.Print();
Point p4 = p3 - p2;
p4.Print();
return 0;
}
1、已知坐标点Point类定义如下:
class Point
{
double x,y;
public:
Point(double a=0,double b=0);//构造函数
friend bool operator>(Point &A,Point &B);//若A点到原点距离大于B点到原点
//距离,则为真;否则为假
friend double GetLength(Point &A,Point &B);//计算点与点之间的距离
};
试编程实现类中带注释语句的函数,每个5分。
#include
#include
using namespace std;
class Point {
double x, y;
public:
Point(double a = 0, double b = 0);
friend bool operator>(Point& A, Point& B);
friend double GetLength(Point& A, Point& B);
};
Point::Point(double a , double b ) {
x = a; y = b;
}
bool operator>(Point& A, Point& B) {
return A.x * A.x + A.y * A.y > B.x * B.x + B.y * B.y;
}
double GetLength(Point& A, Point& B) {
return abs(A.x * A.x + A.y * A.y - B.x * B.x + B.y * B.y);
}
int main() {
Point p1(2, 3);
Point p2(4, 5);
if (p1 > p2) {
cout << "p1 > p2" << endl;
}
else {
cout << "p1 <= p2" << endl;
}
double distance = GetLength(p1, p2);
cout << "The distance of p1 and p2 is: " << distance << endl;
return 0;
}