C++类和对象知识巩固:相关习题解析

目录

1,求下面析构的顺序

2,以下调用了多少次拷贝构造

3,计算日期到天数的转换

4,日期差值

5,打印日期

6,累加天数

7,求1+2+3...n,要求不能使用乘除法、for、while、if、else、switch等关键字及判断语气


1,求下面析构的顺序

//1,求析构的顺序
C c;
int main() 
{
	A a;
	B b;
	static D d; 
	return 0;
}

答:静态对象在程序启动时被创建,并且其存储空间在整个程序的运行期间都存在。它们不依赖于特定的作用域,不会因为某个函数或代码块的结束而被销毁

所以先析构局部的,再析构静态的

"对象创建时会调用构造函数来完成初始化。即便对象 d 是静态的,也是在程序执行到相应语句时才进行初始化"。

所以构造的顺序是  C  A  B  D

析构先析构局部对象 A B,再析构静态对象 C D,先创建的后析构,后创建的先析构

所以析构的顺序是  B  A  D  C

2,以下调用了多少次拷贝构造

class Weiget 
{
public:
	Weiget()
	{}
	Weiget(const Weiget& w) 
	{
		cout << "Weiget(const Weiget& w)" << endl;
	}
};
Weiget f(Weiget u) 
{
	Weiget v(u);
	Weiget w = v;
	return w;
}
int main() 
{
	Weiget x;
	Weiget y = f(f(x));
	return 0;
}

在做这个题目之前,我们先了解一段类似的代码,以下会进行几次拷贝构造

class A
{
public:
	A()
	{
	}
	A(const A& a)
	{
		cout << "A(const A& a)" << endl;
	}
};
A f(const A a)
{
	return a;
}
int main()
{
	A a1;
	A b = f(a1);
	return 0;
}

在不考虑优化的情况下,这段代码中会执行三次拷贝构造函数。

 

第一次是在函数 f 调用时,将实参 a1 传递给形参 a ,会调用一次拷贝构造函数。

 

第二次是在函数 f 中返回对象 a 时,会调用一次拷贝构造函数。

 

第三次是在 main 函数中,将函数 f 的返回值赋给 b 时,会调用一次拷贝构造函数。

在一些编译器优化的情况下,第二次和第三次拷贝构造可能会合并成一次。返回的 a 时候又立马赋值给了对象 b,所以一些编译器可能会做优化。以避免不必要的拷贝操作,提高程序的性能。

有了上面的案例,我们做这个题就是信手拈来的事了

一共调用了 7 次拷贝构造,如果不做优化就是 9 次拷贝构造

3,计算日期到天数的转换

计算日期到天数转换_牛客题霸_牛客网

日期类中判断日期是否合法与这个题目类似

除掉本月外,计算每个月的天数相加,再加上本月的天数

#include <iostream>
using namespace std;

int GetMonthDays(int year, int month) 
{
    int MonthDays[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    if(month == 2 && (((year % 4 ==0)&&(year %100 !=0)) || year%400==0))
    {
        return 29;
    }
    return MonthDays[month];

}
int main() 
{
   int year,month,day;
   cin >> year >> month >> day;
   int days = 0;
   for(int i = 1; i < month; ++i) 
   {
      days += GetMonthDays(year,i);
   }
   days += day;
   cout <<days <<endl;
}

4,日期差值

日期差值_牛客题霸_牛客网

我们先计算年,再算月份,最后算天数

年的天数:除掉该年,计算从 1 到该年之前的天数相加,闰年366,平年365

月的天数:  除本月,计算从1月到该月之前的月份天数相加,闰年2月29,平年28

天的天数:直接加上,最后还需要多加一天,因为题目说连续的日期算两天。

#include <iostream>
using namespace std;
bool isleapyear(int year) 
{
    if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) 
    {
        return true;
    }
    return false;
}
int SincetoBefore(int year,int month,int day) 
{
    int days = 0; 
    //加年的天数,从第一年开始加
    for(int i = 1; i < year; ++i) 
    {
        days += isleapyear(i) ? 366 : 365; 
    }
    //加月份的天数
    int Monthdays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    for(int i = 1; i< month; ++i) 
    {
        if(i == 2 && isleapyear(year)) 
        {
            days += Monthdays[i];
        }
        else 
        {
             days += Monthdays[i];
        }
    }
    //加天数
    days += day;
    return days;
}
int main() 
{
    int year1, month1, day1;
    int year2, month2, day2;
    scanf("%4d%2d%2d",&year1,&month1,&day1);  //需要控制输入格式
    scanf("%4d%2d%2d",&year2,&month2,&day2);
    int days1 = SincetoBefore(year1,month1,day1);
    int days2 = SincetoBefore(year2,month2,day2);
    int day =  days1 > days2 ? days1-days2 +1 : days2 -days1+1; //输出的时候需要多加一天,题目说连续的日期算两天
    cout << day << endl;
    
}

 5,打印日期

打印日期_牛客题霸_牛客网

相对于就是把天数转成日期

1,计算月份,和剩余的天数,不断减,直到这个天数小于该月的天数,这和日期类中的日期加天数类似

2,我们有三个变量年、月、日 需要打印,所以我就用了一个简单的日期类打印,直接传值过去打印

#include <iostream>
using namespace std;

//日期类实现打印功能
class Date
{
public:
    Date(int year = 0,int month = 1,int day = 1) 
    {
        _year = year;
        _month = month;
        _day  = day;
    }
   void Print() 
   {
     if(this->_month> 9 && this->_day > 9) 
        cout << _year <<"-"<<_month <<"-"<<_day <<endl;
     else if(this->_month > 9 && this->_day <=9) 
        cout << _year <<"-"<<_month <<"-0"<<_day <<endl;
    else if(this->_month <= 9 && this->_day >9) 
        cout << _year <<"-0"<<_month <<"-"<<_day <<endl;
    else
        cout <<_year << "-0" <<_month <<"-0" <<_day;
   }
private:
    int _year;
    int _month;
    int _day;
};

//计算出月份和剩的天数
void Date_Print(int year, int days) 
{
    int month = 1;
    int monthDays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    while(days > monthDays[month]) 
    {
        if(month == 2 &&(((year % 4 == 0)&&(year%100!=0)) ||year %400 == 0)) 
            days -= 29;
        else
             days -= monthDays[month];
        ++month;
        //月超出了1月,年进位,月置成 1
        if(month == 13) 
        {
            ++year;
            month = 1;
        }
    }
    Date d1(year,month,days);  //把年月日,传给日期类打印
    d1.Print();
}

int main() 
{
    int year = 0;
    int days = 0;
    while (cin>>year>>days) 
    {
        Date_Print(year,days);
    }
    return 0; 
}

6,累加天数

日期累加_牛客题霸_牛客网
 

与日期类中日期加天数类似

#include <iostream>
using namespace std;

class Date 
{
public:
    Date(int year = 0, int month = 1, int day = 1) 
        :_year(year)
        ,_month(month)
        ,_day(day)
    {}
    //日期累加
    Date& calculateDate(int days) 
    {
        _day += days;
        int Monthdays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
        while (_day > Monthdays[_month])  
        {
            if(_month == 2 && ((_year % 4 == 0 && _year % 100 != 0) 
            ||( _year %400 ==0))) 
            {
                _day -= 29;
            }
            else 
            {
                 _day -= Monthdays[_month];
            }
            ++_month;
            if(_month == 13) 
            {
                ++_year;
                _month = 1;
            }
        }
        return *this;
    }
    //打印
    void Print() 
    {
       printf("%d-%02d-%02d\n", _year, _month, _day);
    }
private:
    int _year;
    int _month;
    int _day;
};
int main() 
{
    int m = 0;
    cin >> m; 
    int year, month, day, days;
    for(int i = 0; i< m; ++i) 
    {
        cin >> year >> month >> day >> days;  
        Date d(year,month,day);
        d.calculateDate(days);
        d.Print();
    }
}

7,求1+2+3...n,要求不能使用乘除法、for、while、if、else、switch等关键字及判断语气

求1+2+3+...+n_牛客题霸_牛客网
 

把 _sum 和 _i 设置成静态的变量,这样就属于所有的对象,而不是属于某个对象

 

Sum* p = new Sum[n];  n是几就会调用几次构造函数,相对于是一个数组,数组里面存的

是对象,n 是几就表示有几个对象,对象在创建的时候就会自动调用构造函数完成初始化

class Sum 
{
public:
    Sum() 
    {
        _sum += _i;
        ++_i;
    }
    static int GetNum() 
    {
        return _sum;
    }
private:
    static int _sum;
    static int _i;
};
int Sum::_sum = 0;
int Sum::_i = 1;

class Solution {
public:
    int Sum_Solution(int n) 
    {
        Sum* p = new Sum[n];
        return Sum::GetNum();
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值