我想说
每天坚持一点点,坚持带来大改变
今天是刷题的第_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;
}