【笔试刷题训练】day_14

我想说

每天坚持一点点,坚持带来大改变
今天是刷题的第_14天,加油!


一、选择题

在这里插入图片描述
成员是否可以访问取决于继承之后的权限,与this指针无关
this指针的作用:

类中的成员函数只有一份,对于多个对象都是调用的这一个代码,那么如何区分是谁调用的该函数呢?实际上,成员函数有一个默认隐藏的形参this,每一个对象调用成员函数的时候都会把该对象的地址传递给this,这样在调用的时候就可以知道是哪一个对象调用的该成员函数了

所以,this指针的作用就是保证每个对象拥有自己的数据成员,但共享处理这些数据的代码

在这里插入图片描述
A:对于 .* :: sizeof . :?这五个运算符不可以重载
B:const对象的指针是const *类型,所以不可以调用普通成员函数,因为const指针无法赋值给普通指针(权限放大),所以只能调用const类型成员函数
C:构造函数不可以是虚函数!析构函数可以是虚函数
D:重载是根据:参数的个数和类型来判断,和返回值无关。因为生成的符号表中的函数名字主要是通过参数个数和类型来命名。

在这里插入图片描述
A: 一个类会生成6个默认成员函数 ✔(引用操作符就是取地址成员函数)
B: 一个类只能有一个析构函数 ❌
C: 析构函数可以为virtual,但是不能被重载,因为没有参数 ❌
D: 类的构造函数如果不是public,可以通过定义一个静态的public成员函数接口来创建类的实例(这种特殊场景设计模式会涉及到) ❌

在这里插入图片描述
继承和组合的区别
继承:is-a的关系,如学生是一个人,学生类继承自人这个类
组合:has-a的关系,如车子有轮胎、发动机等,那么车这个类里的成员包括轮胎类对象、发动机类对象
在继承和组合中,优先选择组合
因为继承本身就是打破了面向对象设计中的封装这一特性,子类可以看到父类的成员实现。而组合是不可以看到类内部的实现的,只是可以通过对象来使用相关接口,维持了封装性。
设计程序的原则有一条是:低耦合高内聚。所以为了尽量减少不同类之间的关联,尽量使用组合。

因此答案选择 C

5.
在这里插入图片描述
A:用父类的指针调用,符合多态的第一条件,具体调用子类还是父类,需要看是否满足多态的第二个条件,即:父类的方法是否为虚函数。 ❌
B:✔
C:重载和子类方法无关,啥时候都可以使用
D:a是父类类型的指针,把子类对象B的地址赋值给a,a指向子类对象。然后a调用test,参数为float类型,test不是虚函数不会实现多态,所以理应输出1
但是注意,a是指针,题目的调用方法是a.test(1.1),显然会编译报错! ❌

在这里插入图片描述
如下分析:
在这里插入图片描述
7.
在这里插入图片描述
这一题利用全局函数fun,分别把不同的对象传递给fun。但是会发现fun的形参是父类型B0的对象,并不是父类型的引用,所以无论如何都不会构成多态,形参发生切片指向父类那一部分,调用的永远是B0的display,所以选A

在这里插入图片描述
A: 构造函数,对象还没构造出来,而虚函数是放在虚函数表,在调用的时候动态地根据this指针所指向的具体的对象是父类还是子类对象来去动态调用的。所以还没有对象不可能去调用!
B:析构函数可以定义为虚函数,如果父类指针指向子类对象,而去释放父类指针的时候,就会去调用子类的析构函数,防止父类对象析构而子类对象没析构而产生的内存泄漏问题
C:内联成员函数会展开,虚函数需要函数地址,所以不可以定义为虚函数
D:静态函数没有this指针,调用虚函数需要对象的this指针去调用,所以不可以定义为虚函数!

二、编程题

1. 幸运的袋子

👉 题目链接

思路分析

在这里插入图片描述

代码

#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;
int getLuckyPacket(vector<int>& v,int n,int pos,int sum,int mult)
{
    int count = 0;  //记录此次递归的找到的count
    for(size_t i = pos;i<n;++i)   
    {
        sum+=v[i];
        mult*=v[i];
        //此次满足
        if(sum > mult)
        {
            //1+下一个位置 (i+1)
            count += 1 + getLuckyPacket(v, n, i+1,sum,mult);
        }
        //此次不满足,但是该位置为1
        else if(v[i]==1)
        {
            count += getLuckyPacket(v,n,i+1,sum,mult);
        }
        //此时不可以,并且还不是1,说明后面都是大于1,说明后面也肯定不可以了,回溯
        else
        {
            //直接跳出
            break;
        }
        //为for循环的下一次循环做准备
        sum-=v[i];
        mult/=v[i];
        //走到这,可能下一次有重复 如:1 1 3 3 5 7 中3重复
        while(i<n-1 && v[i]==v[i+1])
        {
            ++i;
        }
    }

    return count;
}
int main()
{
    int n;
    cin>>n;
    vector<int> v(n);
    for(size_t i = 0;i<n;++i){
        cin>> v[i];
    }
    sort(v.begin(),v.end());
    //和从0开始,积从1开始
    cout << getLuckyPacket(v,n,0,0,1) <<endl;
    return 0;
}

2. 计算日期到天数的转换

👉 题目链接

这题过于简单,简单说一下:

  • 先计算出该月之前的天数
  • 然后加上此月的天数即可
#include<iostream>
using namespace std;
int get_month_day(int year,int month)
{
    //存放每月的天数
    static int array[13]={0,31,28,31,0,31,30,31,31,30,31,30,31};
    //如果是2月并且是闰年
    if(2==month && (year%4==0&&year%100!=0 || year%400==0))
    {
        return 29;
    }
    return array[month];
}
int main()
{
    int year,month,day;
    while(cin>>year>>month>>day)
    {
        //先计算前month-1个月有多少天
        int theday = 0;
        for(int i = 0;i<=month-1;++i)
        {
            theday+=get_month_day(year, i);
        }
        theday+=day;
        cout << theday << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2021狮子歌歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值