【C++二级易错题整理】历年真题及最新大纲模拟题之C++篇(二)(零基础,选择题也能35+)

写在最前

  在我的上一篇博文:“公共基础知识篇(一)”中,根据历年真题及最新大纲模拟题,个人整理了一些公共基础知识部分的易错题。本文继续介绍C++二级考试选择题部分的“重头戏”,分数值占到选择题总分75%的C++知识部分。


重载、重载运算符


  双目运算符“=、( )、[ ]、->”不能重载为类的友元函数。

  C++中,赋值运算符=、下标运算符[]、调用运算符()、成员访问指针运算符->必须重载为成员函数。

  不能重载的运算符只有5个:’.’、’.*’、’::’、‘sizeof’、’?’。

  函数不能仅仅只基于不同的返回类型而实现重载。

  析构函数没有返回值,没有形参,所以析构函数不能重载。(同样构造函数也没有返回值)。

  重载运算符的函数不能有默认的参数,否则就改变了运算符的参数个数。


下列关于重载运算符的说法正确的是()。
A)运算符 :: 不能被重载,运算符 . 必须作为类成员重载
B)运算符 [ ] 不能被重载,运算符 = 必须作为类成员重载
C)运算符 * 不能被重载,运算符 ( ) 必须作为类成员重载
D)运算符 . 不能被重载,运算符 [ ] 必须作为类成员重载

【解析】本题考查运算符重载,不能重载的运算符只有5个:’.’、’.*’、’::’、‘sizeof’、’?:’。C++规定有的运算符(如赋值运算符、下标运算符、函数调用运算符)必须定义为类的成员函数,只有D选项正确。


有如下定义:
class MyClass{
public:
 【 】
private:
 int data;
}
若要为MyClass类重载流输入运算符“>>”,使得程序中可以“cin>>obj;”的形式改变MyClass类的对象obj中的数据成员data的值,则【 】处的声明语句应为()。
A)friend istream& operator >>(istream& is, MyClass& a);
B)friend istream& operator >>(istream& is, MyClass a);
C)istream& operator >>(istream& is, MyClass& a);
D)istream& operator >>(istream& is, MyClass a);

【解析】本题答案为A。

类似“<<”和“>>”这样的运算符只能重载为类外的非成员函数,所以在类内声明时要加上friend表示这是个友元函数;

为什么类似“<<”和“>>”这样的运算符只能重载为类外的非成员函数?

因为:运算符的左操作数不是我们自定义的类对象(比如标准库里的类对象或者实数等等),那么重载运算符函数就不能定义在类内。


下面是重载为非成员函数的运算符的函数声明,其中错误的是()。
A)Fraction opreator +(Fraction, Fraction);
B)Fraction opreator -(Fraction);
C)Fraction& opreator =(Fraction&, Fraction);
D)Fraction& opreator +=(Fraction&, Fraction);

【解析】

运算符重载为类的成员函数,函数参数个数=原操作数个数 - 1;

运算符重载为非成员函数,函数的参数个数=原操作数个数(后置++,–除外);

B选项,当-表示的是负号,则成立;

C选项,C++强制规定,重载赋值运算符函数,只能是类的非静态成员函数。


通过运算符重载,可以改变运算符原有的()。
A)优先级
B)结合性
C)操作数类型
D)操作数个数

【解析】重载不能改变运算符运算对象的个数;不能改变运算符的优先级别;不能改变运算符的结合性。


若要在Viz类中将*重载为一元运算符,下列重载函数声明中肯定有错的是()。
A)Viz opreator *();
B)Viz operator *(Viz);
C)int operator *(Viz); //int表示函数返回的是int型,不是错的!
D)Viz operator *(Viz, Viz);

【解析】将*重载为一元运算符,所以只有一个操作数,而D选项有两个操作数,所以D错误。


下面是重载为非成员函数的运算符函数原型,其中错误的是()。
A)Fraction operator +(Fraction);
B)Fraction operator -(Fraction);
C)Fraction operator *(Fraction);
D)Fraction operator /(Fraction);

【解析】将*重载为一元运算符,所以只有一个操作数,而D选项有两个操作数,所以D错误。


设c1和c2是类MyClass的对象,若将前缀运算符“–”和运算符“/”作为类MyClass的友元函数重载,则表达式–c1/c2等价于()。
A)operator/(c1.operator–(), c2)
B)operator/(operator–(c1),c2)
C)c1.operator–().operator/(c2)
D)c2.operator/(operator–(c1))

【解析】

友元函数不是类的成员函数,所以友元函数的调用不需要使用类对象;

“–”优先级高于“/”!所以先执行“–”运算符重载函数,之后执行“/”运算符重载函数;

如果"–"和“/”重载为类的成员函数,则C选项正确。


重载类型转换运算符


类中重载类型转换运算符的一般声明 :operator T() const;


若要对类Value中重载的类型转换运算符long进行声明,下列选项中正确的是()。
A)operator long() const;
B)operator long(Value) const;
C)long operator long();
D)long operator long(Value);

【解析】

本题考查类型转换函数,其一般形式如下:operator 类型名(){实现转换的语句};

在函数名前面不能指定函数类型,函数没有参数,所以A选项正确。


有如下类定义:
class MyClass{
 public:
MyClass(double d=0.0): val(d) { }
 ___________ //类型转换运算符double的定义
private:
 double val;
};
若要使语句序列
  MyClass x(2.1);
  cout<<double(x);
能够正常运行,横线处的语句应为()。
A)operator double() const {return val;}
B)friend operator double() const {return val;}
C)double operator() const {return val;}
D)friend double operator() const {return val;}

【解析】题目需要定义类型转换运算符double,类型转换运算符是一种特殊的类成员函数,它定义将类类型的值转变为其他类型值,由于转换函数必须是成员函数,选项B、D错误;另外转换函数不能指定返回类型,并且形参列表必须为空,选项C错误;所以double类型转换运算符的定义为:operator double() const{return val};答案为A。


常对象、常数据成员、常成员函数


常数据成员

 ◆ 常数据成员必须进行初始化,并且不能被更新。

 ◆ 常数据成员不能在声明时赋初始值(普通数据成员也是),常数据成员必须在构造函数初始化列表进行初始化;普通数据成员在初始化列表和函数体中初始化均可。

 ◆ PS:类的成员对象若要传入参数初始化,则必须在构造函数初始化列表进行;(成员对象:当一个类的成员是另一个类的对象时,这个对象就叫成员对象。)

常对象

 ◆ ⭐常对象可以调用常成员函数,不能调用非const成员函数;非const对象,可以调用普通成员函数和常成员函数。

 ◆ 常对象的成员函数不一定都是常成员函数;同样的常对象的数据成员不一定都是常数据成员。

 ◆ 常对象一旦初始化,常对象的数据成员便不允许修改,而不是说常对象的数据成员都是常数据成员。

 ◆ PS:定义常对象有两种方法,1. Point const a; 2. const Point a;(同样的,定义变量或指针时,const放前放后意义一样,如:1. const double a; double const a; 2. const int *p; int const *p; 但是定义指针常量时,只能用 int * const p;)
常成员函数

常成员函数

 ◆ 常成员函数不更新对象的数据成员。

 ◆ 常成员函数的const关键字可以被用于参与对重载函数的区分。

 ◆ ⭐通常非const成员函数需要定义一个const版本的重载函数,以方便定义常对象后调用常成员函数。
  ◈ 如果常对象调用的常成员函数返回的是指向当前对象的指针(或返回的是当前对象),那么此常成员函数的声明的返回类型要加const,例如:

    ◊ 成员函数返回指向当前对象的指针
      const *Point fun1();    //非const成员函数的类内声明;
      const *Point fun1() const; //习惯上要再声明一个常成员函数作重载函数,注意到此函数声明有两个const;

    ◊ 成员函数返回指向当前对象
      const Point fun1();    //非const成员函数的类内声明;
      const Point fun1() const; //习惯上要再声明一个常成员函数作重载函数,注意到此函数声明有两个const;

    ◊ ⭐注意,如果一个类中声明以下4个重载函数:
      ① Point fun1();
      ② const Point fun1();
      ③ Point fun1() const;
      ④ const Point fun1() const;
     【解析】①和②是冲突的,因为无法区分仅按返回类型区分的重载函数;③和④是冲突的,也是因为无法区分仅按返回类型区分的重载函数。
     所以正确的重载函数搭配有3种:

      ◊ ①和③搭配:
        Point fun1();             //函数返回非const对象
        Point fun1() const;          //函数返回非const对象
       [解析]适用于定义常对象后调用常成员函数,常成员函数返回类型是非const的Point类对象。

      ◊ ①和④搭配(这里把返回类型改为指针,因为常用):
        Point *fun1() {return this; };      //函数返回指向本对象的指针
        const Point *fun1() const { return this; };//函数返回指向本常对象的指针,第一个const说明返回的是指向常对象的指针,第二个const说明此函数是常函数

       [解析]适用于定义常对象后调用常成员函数,常成员函数返回类型是常Point类对象(如return *this;)。

      ◊ ②和④搭配:
        const Point fun1();          //函数返回常对象
        const Point fun1() const;       //函数返回常对象
       [解析]适用于定义常对象后调用常成员函数,常成员函数返回类型是常Point类对象。

       ②和③搭配:
        const Point fun1();
        Point fun1() const;
       [解析]虽然搭配合法,但是似乎不存在这种搭配。


内联函数


⭐下列关于内联函数的叙述中,错误的是()。
A)内联函数的定义必须出现在内联函数第一次被调用之前
B)内联函数主要解决程序的运行效率问题
C)类体中定义的函数都是内联函数
D)内联函数不能有参数

【解析】内联函数的函数定义必须出现在内联函数第一次被调用之前;内联函数可以避免函数频繁调用时的开销,提高程序运行效率;在类定义体内部定义的成员函数,编译器都将其视为内联函数(包括构造函数);A、B、C正确;内联函数也可以有参数,D错误,答案为D。


在C++中,用来取代C中的预处理宏函数的是()。
A)重载函数
B)友元函数
C)递归函数
D)内联函数

【解析】内联函数被发明出来就是为了取代C中的宏,故选D。(联想到内联函数与一般函数不同之处就在于函数调用的预处理)


有如下类及函数的定义:
class Wow{
 int k;
public:
 Wow(int n=0): k(n) { }
 int incre() { return ++k;}
 int decre();
 void show() const;
};
int Wow::decre() { return --k; }
inline void display(Wow w) { w.show(); }
void Wow::show() const { cout<<k; }
在上面所定义的函数中,内联函数的个数是()。
A)1
B)2
C)3
D)4

【解析】类定义体内部定义的函数,编译器都默认为内联函数(包括构造函数!!),类定义体外部定义的函数,使用关键字inline修饰的函数为内联函数,所以内联函数有:Wow(int n=0)、incre()、display(Wow w),答案为C。


有如下定义:
class Box{
public:
 double GetLength() {return length;}
 double GetWidth();
 double GetHeight();
private:
 double length, width, height;
};
inline double Box::GetWidth() {return width;}
double Box::GetHeight() {return height;}
在成员函数GetLenth、GetWidth和GetHeight中,内联函数有()。
A&

  • 8
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
全国计算机二级C++模拟题是为了评估考生在C++编程方面的能力而设计的一套题目。这些题目涵盖了C++语言的基本语法、面向对象编程、文件操作、异常处理等方面的知识点。以下是一道典型的全国计算机二级C++模拟题: 题目:编写一个C++程序,实现一个简单的学生信息管理系统。要求如下: 1. 定义一个学生类(Student),包含学号(id)、姓名(name)、年龄(age)三个成员变量,以及设置和获取这些成员变量的成员函数。 2. 定义一个学生信息管理类(StudentManager),包含一个学生数组作为成员变量,以及添加学生信息、删除学生信息、查找学生信息等功能的成员函数。 3. 在主函数中,创建一个学生信息管理对象,通过调用其成员函数实现对学生信息的管理。 示例代码如下: ```cpp #include <iostream> #include <string> using namespace std; class Student { private: int id; string name; int age; public: void setId(int studentId) { id = studentId; } void setName(string studentName) { name = studentName; } void setAge(int studentAge) { age = studentAge; } int getId() { return id; } string getName() { return name; } int getAge() { return age; } }; class StudentManager { private: static const int MAX_SIZE = 100; Student students[MAX_SIZE]; int count; public: StudentManager() { count = 0; } void addStudent(Student student) { if (count < MAX_SIZE) { students[count] = student; count++; cout << "添加学生信息成功!" << endl; } else { cout << "学生信息已满,无法添加!" << endl; } } void deleteStudent(int studentId) { for (int i = 0; i < count; i++) { if (students[i].getId() == studentId) { for (int j = i; j < count - 1; j++) { students[j] = students[j + 1]; } count--; cout << "删除学生信息成功!" << endl; return; } } cout << "未找到该学生信息!" << endl; } void searchStudent(int studentId) { for (int i = 0; i < count; i++) { if (students[i].getId() == studentId) { cout << "学号:" << students[i].getId() << endl; cout << "姓名:" << students[i].getName() << endl; cout << "年龄:" << students[i].getAge() << endl; return; } } cout << "未找到该学生信息!" << endl; } }; int main() { StudentManager manager; Student student1; student1.setId(1); student1.setName("张三"); student1.setAge(18); manager.addStudent(student1); Student student2; student2.setId(2); student2.setName("李四"); student2.setAge(19); manager.addStudent(student2); manager.searchStudent(1); manager.searchStudent(3); manager.deleteStudent(1); manager.searchStudent(1); return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值