C++程序设计期末考试复习试题及解析 3(自用~)
创始人
2024-02-01 15:21:10
0

DDL

  • 1.题目及分析
    • 1.对象数组的析构顺序
    • 2.浅拷贝的隐患
      • delete p 还是 delete[]p ?
      • 类似的题,自行查阅
    • 3.常数据成员的初始化
    • 4.默认构造函数
    • 5.cin、cout所属类
    • 6.重载
    • 7.静态数据成员
    • 8.多态
    • 8.联编
    • 9.内联函数
    • 10.引用
    • 11.static
    • 12.构造Complex类
    • 13.静态成员函数
    • 14.抽象类
    • 15.标识符
    • 16.指针数组
    • 17.不可嵌套定义,可嵌套调用
    • 18.可见性 、存在性
    • 19.虚函数
    • 20.子类重写虚函数的权限
    • 21.虚析构函数
    • 22.重载、覆盖
    • 23.继承
    • 24.类与对象
    • 25.友元关系
    • 25.公有继承
    • 26.多态
    • 27.
    • 28.面向对象
    • 29.四要素
    • 30嵌套
  • 2.更新日志

1.题目及分析

1.对象数组的析构顺序

在这里插入图片描述

#include 
using namespace std;class T {
public:~T() { cout << "Destroying..." << i << endl; }void Setij(int a, int b) { i = a, j = b; }int GetMuti() { return i * j; }
protected:int i, j;
};
int main()
{T* p = new T[5];for (int j = 0; j < 5; ++j) p[j].Setij(j, j);for (int k = 0; k < 5; ++k) cout << "Multi[" << k << "] is:" << p[k].GetMuti() << endl;//程序结束并不会隐式地调用析构函数,需要显式调用析构函数//析构顺序与构造顺序相反delete[]p;return 0;
}

在这里插入图片描述

2.浅拷贝的隐患

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


#include 
using namespace std;class Vector {
public:Vector(int s = 100);~Vector();int& Elem(int idx);void Display();void Set();
protected:int size;int* buffer;
};Vector::Vector(int s)
{buffer = new int[size = s];    //巧妙1: 初始化size的同时也初始化了buffer
}
Vector::~Vector()
{cout << "扫尾工作..." << endl;delete []buffer;
}int& Vector::Elem(int idx)
{if (idx < 0 || idx >= size){cout << "error in index" << endl;exit(-1);}return buffer[idx];
}void Vector::Display()
{for (int i = 0; i < size; ++i)cout << Elem(i) << endl;
}void Vector::Set()
{for (int i = 0; i < size; ++i)Elem(i) = i + 1;    //巧妙2: 利用返回值为引用,直接修改了buffer(i)
}int main()
{	Vector a(10);Vector b(a);a.Set();b.Display();return 0;
}

在这里插入图片描述

可以很清楚看到浅拷贝所造成的错误:在析构的时候会重复析构,这是由于浅拷贝时,b的buffer指针和a的buffer指针指向的是同一片空间

如何更改?
换为深拷贝!
即弃用默认拷贝构造函数,自己写一个拷贝构造函数

#include 
using namespace std;class Vector {
public:Vector(int s = 100);Vector(const Vector& v);   //拷贝构造函数~Vector();int& Elem(int idx);void Display();void Set();
protected:int size;int* buffer;
};Vector::Vector(int s)
{buffer = new int[size = s];    //巧妙1: 初始化size的同时也初始化了buffer
}
Vector::Vector(const Vector& v)
{//照猫画虎 重新开辟空间,使得通过调用拷贝构造函数创建的对象的buffer指向另一片空间this->buffer = new int[this->size = v.size];//拷贝数据  [也可不加this指针进行访问]for (int i = 0; i < size; ++i)buffer[i] = v.buffer[i];
}
Vector::~Vector()
{cout << "扫尾工作..." << endl;delete []buffer;
}int& Vector::Elem(int idx)
{if (idx < 0 || idx >= size){cout << "error in index" << endl;exit(-1);}return buffer[idx];
}void Vector::Display()
{for (int i = 0; i < size; ++i)cout << Elem(i) << endl;
}void Vector::Set()
{for (int i = 0; i < size; ++i)Elem(i) = i + 1;    //巧妙2: 利用返回值为引用,直接修改了buffer(i)
}int main()
{	Vector a(10);Vector b(a);a.Set();b.Display();return 0;
}

在这里插入图片描述
改为深拷贝后,a、b对象不会相互影响,由于b未调用set()函数,所以其buffer里面的数据仍为随机值

delete p 还是 delete[]p ?

#include 
using namespace std;
int main()
{int* p1 = new int(5);  //只分配一个int类型的空间,并初始化为5cout << *p1 <<" "<< p1[0] << endl;delete p1;int* p2 = new int[5];  // 指向数组p2[0] = 1;p2[1] = 10;cout << *p2 << " " << p2[0] << " " << p2[1] << endl;delete[] p2;  //依次销毁p2所指向的完整完整空间return 0;
}

在这里插入图片描述

delete []p 是指 释放p所指向的完整空间

记清楚两者的适用条件即可

类似的题,自行查阅

在这里插入图片描述
在这里插入图片描述

3.常数据成员的初始化

常数据成员名只可在初始化列表中进行
(上机在VS2019尝试后,发现在定义时初始化也能编译通过,但并不建议这样做)

4.默认构造函数

默认构造函数(default constructor)就是在没有显式提供初始化式时调用的构造函数。
它由不带参数的构造函数,或者为所有的形参提供默认实参的构造函数定义

①
class T{
public:T(){}
protected:int x;
}②
class T{
public:T(int xx = 0) {}
protected:int x;
}

5.cin、cout所属类

在这里插入图片描述
B
cin 属于 istream类
cout 属于 ostream类

6.重载

在这里插入图片描述
A
类模板不可以重载,但是函数模板可以重载。

7.静态数据成员

在这里插入图片描述
静态数据成员指的是 static修饰的数据成员
A

8.多态

在这里插入图片描述
A

多态分为4类: 重载多态 、 强制多态、参数多态、包含多态
前两种又被称为专用多态
后两种又被称为通用多态

前三种的绑定工作在编译连接阶段即可完成
包含多态的绑定工作在程序运行阶段才可完成

8.联编

在这里插入图片描述
B
在这里插入图片描述

多态分为静态多态(编译时多态、静态联编、早绑定)和动态多态(运行时多态、动态联编、晚绑定)

9.内联函数

在这里插入图片描述
正确
在这里插入图片描述

10.引用

在这里插入图片描述

在这里插入图片描述

11.static

在这里插入图片描述
static修饰的数据成员为该类的所有对象_共享___

12.构造Complex类

在这里插入图片描述

#include 
using namespace std;class Complex {
public:Complex(double rr = 0.0 ,double ii = 0.0):r(rr),i(ii){}void show() { cout << r << " " << i << endl; }Complex operator+(const Complex& c) {return Complex(this->r + c.r, this->i + c.i);}
private:double r, i;
};int main()
{Complex c1(-1, 4), c2(2, 5);c1.show();c2.show();Complex c3 = c1 + c2;c3.show();return 0;
}

在这里插入图片描述

13.静态成员函数

在这里插入图片描述
B

#include 
using namespace std;class T {
public:static void show_x() { return this->x; }  //错误,this指针只存在于非静态函数内部
private:static int x;
};int T::x = 1;  //静态数据成员类外初始化int main()
{return 0;
}

在这里插入图片描述

14.抽象类

在这里插入图片描述

#include 
using namespace std;
#include const double PI = acos(-1);class CShape {
public:virtual double GetLength() const = 0;
};class CSqure :public CShape {
public:CSqure(double x, double y):x(x),y(y){}double GetLength()const { return 2 * (x + y); }
private:double x, y;
};class CCircle :public CShape {
public:CCircle(double r):r(r){}double GetLength()const { return 2 * PI * r; }
private:double r;
};int main()
{CSqure c1(1, 2);cout << c1.GetLength() << endl;CCircle c2(1);cout << c2.GetLength() << endl;return 0;
}

在这里插入图片描述

15.标识符

在这里插入图片描述

16.指针数组

在这里插入图片描述

17.不可嵌套定义,可嵌套调用

在这里插入图片描述

18.可见性 、存在性

在这里插入图片描述

19.虚函数

在这里插入图片描述
虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。

20.子类重写虚函数的权限

#include 
using namespace std;class B {
public:B(){}B(int i) { b = i; }virtual void virfun(){cout << "B::virfun() called.\n";}
private:int b;
};class D :public B {
public:D(){}D(int i, int j) :B(i) { d = j; }
private:int d;void virfun(){cout << "D::virfun() called.\n";}
};void fun(B* obj)
{obj->virfun();
}int main()
{D* pd = new D;fun(pd);return 0;
}


虽然在子类中声明了private,但其实仍然可以调用虚函数

虚函数编译时的访问权限仅仅是和调用者(指针、引用)的类型有关,编译器只要知道这个类型有一个可以访问的虚函数就行了,并不查看具体对象类型中该虚函数的访问权限

简而言之,基类是public权限即可成功调用虚函数

21.虚析构函数

在这里插入图片描述

22.重载、覆盖

在这里插入图片描述
在这里插入图片描述

23.继承

在这里插入图片描述

24.类与对象

在这里插入图片描述

25.友元关系

在这里插入图片描述

A

友元关系破坏了封装性,可提高程序的运行效率

25.公有继承

在这里插入图片描述
C

只可访问公有成员

26.多态

在这里插入图片描述
在这里插入图片描述

27.

在这里插入图片描述
在这里插入图片描述

28.面向对象

面向对象将数据和对数据的操作作为一个相互依赖,不可分割的整体,采用了数据抽象和信息隐蔽技术。

29.四要素

抽象性、封装性、继承性和多态性

30嵌套

在C++中,函数的定义不可以嵌套,类的定义可以嵌套。

2.更新日志

2022.11.19 整理

欢迎交流、讨论、指正~
不正确、不理解之处欢迎评论留言~

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...