温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C++类中const修饰的成员函数及日期类怎么使用

发布时间:2023-01-30 09:18:23 来源:亿速云 阅读:156 作者:iii 栏目:开发技术

这篇文章主要介绍“C++类中const修饰的成员函数及日期类怎么使用”,在日常操作中,相信很多人在C++类中const修饰的成员函数及日期类怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++类中const修饰的成员函数及日期类怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    一.const修饰类的成员函数

    1.问题引出:

    给出一段简单的代码

    代码段:

    #include <iostream>
    using std::cin;
    using std::cout;
    using std::endl;
     
    class Date1
    {
    public:
    	Date1(int year = 2000)             类的全缺省构造函数(可无参调用)
    	{
    		_year = year;
    	}
     
    	void Prin()
    	{
    		cout << "Print Date:" << _year << endl;
    	}
     
    private:
    	int _year;
    };
     
     
     
    int main()
    {
    	const Date1 a;                       定义一个const修饰的对象a(该对象只可读,不可被写入)
    	a.Prin();
     
    	return 0;
    }

    该段程序会编译报错:

    C++类中const修饰的成员函数及日期类怎么使用

    2.问题分析

    上述代码段出错的原因要从类的成员函数的隐含参数this指针出发进行分析:

    C++类中const修饰的成员函数及日期类怎么使用

    注意:

    • 由于a是const修饰的对象,因此&a 取出的是 const Date *类型的指针,该指针只可对a对象的内存空间进行读取操作而不可进行写入操作(该指针的权限为只可读取不可写入)。

    • Prin函数的形参是Date * const this指针,该类型指针同时具有读取和写入内存空间的权限。

    • 将&a赋给Prin的形参this,就会使指针的读写权限被放大,因此编译无法通过(指针是灵活而危险的存在,编译器只允许其读写权限被缩小而不允许其权限被放大)

    3.const修饰类的成员函数 

    我们知道类的每个成员函数都有一个隐含的this指针形参(类型为:类名*const this)。

    为了使被const修饰的对象(比如是上面代码段中的a)可以调用其成员对象,C++规定可以用const来修饰类的成员函数。

    类中被const修饰的“成员函数”称为const成员函数,const修饰类成员函数,本质上修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员变量进行修改。(修饰后成员函数的this指针形参类型变为:const 类名* const this)

    比如:

    C++类中const修饰的成员函数及日期类怎么使用

    C++类中const修饰的成员函数及日期类怎么使用

    const修饰的对象不可以调用非const修饰的成员函数(类指针传参给this指针时读写权限被放大):

    C++类中const修饰的成员函数及日期类怎么使用

    非const修饰的对象可以调用const修饰的成员函数(类指针传参给this指针时读写权限被缩小):

    C++类中const修饰的成员函数及日期类怎么使用

    const修饰的成员函数内不可以调用其它的非const修饰的成员函数(this指针之间传参时读写权限被放大):

    C++类中const修饰的成员函数及日期类怎么使用

    非const修饰的成员函数内可以调用其它的const修饰的成员函数(this指针之间传参时读写权限被缩小):

    C++类中const修饰的成员函数及日期类怎么使用

    当类的成员函数中没有对类的成员变量进行任何形式的修改操作时,该成员函数最好都用const来修饰(这样安全同时又使得const修饰的对象可以调用该成员函数)以保证代码的健壮性。

    二. 类的两个默认的&运算符重载

    C++类中const修饰的成员函数及日期类怎么使用

    编译器会默认生成两个类的&(取地址)重载用于类的取地址操作(如果我们自定义了类的取地址重载则编译器便不会再生成默认的)

    C++中,内置运算符若要直接作用于类对象则必须经过重载。

    若想取到类对象的地址,我们可以对&运算符进行重载,比如:

    #include <iostream>
    using std::cin;
    using std::cout;
    using std::endl;
     
     
     
    class Date1
    {
    public:
        Date1(int year = 2000)
    	{
    		_year = year;
    	}
     
     
    	Date1* operator& ()               对&进行重载用于非const修饰的对象的取地址
    	{
    		return this;
    	}
     
    	const Date1* operator&() const    对&进行重载用于const修饰的对象的取地址
    	{
    		return this;
    	}
     
    private:
    	int _year;
    };
     
     
    int main()
    {
    	const Date1 a;                     定义一个const修饰的对象a(该对象只可读,不可被写入)
        Date1 b;
     
    	cout << &a << endl;
    	cout << &b << endl;
     
    	return 0;
    }

    C++类中const修饰的成员函数及日期类怎么使用

    C++类中const修饰的成员函数及日期类怎么使用

    这两个默认成员函数一般不用重新自定义 ,编译器默认会生成,编译其默认生成的&重载和上面我们自定义的成员函数应该没有什么区别(至少功能上没区别)。

    三. 日期类小练习 

    日期类头文件:

    为了提高代码的可维护性和可读性,将日期类的成员函数的声明和定义分开写。

    #pragma once
    #include <iostream>
    using std::cout;
    using std::cin;
    using std::endl;
     
    //记录日期的类
    class Date        
    {
    public:
     
    	//Date的构造函数
    	Date(int day=1, int month=1, int year=1);		
    	//获取月份天数的方法
    	int GetMonthday(const int month) const;
    	//类对象的日期打印函数
    	void Print() const;
    	//判断某个日期是星期几,并打印出来
    	void GetWeekDay() const ;
     
     	//一组比较运算符的重载
    	bool operator> (const Date& date)const;				
    	bool operator==(const Date& date)const;
    	//在逻辑上我们只需定义出大于(或小于)和等于的判断函数,剩余的判断函数我们就可以通过复用的方    
        式简化代码书写
    	bool operator<(const Date& date)const;
    	bool operator>=(const Date& date)const;
    	bool operator<=(const Date& date)const;
    	bool operator!=(const Date& date)const;
     
    	//一组日期+(-)整数的操作和+=(-=)整数的操作
    	Date operator+(const int day)const;
    	Date& operator+=(const int day);
    	Date operator-(const int day)const;
    	Date& operator-=(const int day);
    	Date& operator=(const Date& date);
    	
    	//一组前置++(--)和后置++(--)的重载
    	Date& operator++();								 //实现日期类的前置++
    	Date operator++(int);							 //实现日期类的后置++
    	Date& operator--();                              //实现日期类的前置--
    	Date operator--(int);                            //实现日期类的后置--
     
    	//实现时期相减的操作符重载
    	int operator-(const Date& date)const;
    	
    private:
    	int _day;
    	int _month;
    	int _year;
     
    };

    日期类的成员函数的实现:

    #include "Date.h"
     
    //Date的构造函数
    Date ::Date(int day, int month, int year)   
    {
    	_day = day;
    	_month = month;
    	_year = year;
    	if (_year <= 0 || _month <= 0 || _month > 12 || _day <= 0 || _day > GetMonthday(_month))
    	{
    		cout << "date invalued please exit the app" << endl;
    		exit(0);
    	}
    	
    }
    //获取相应月份天数的方法
    int Date::GetMonthday(const int month)const
    {
    	static const int arr[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    	int ret = arr[month - 1];
    	if (((0 == _year % 4 && 0 != _year % 100) || (0 == _year % 400)) && 2 == month)
    	{
    		ret++;
    	}
    	return ret;
    }
    //类对象的日期打印函数
    void Date::Print()const
    {
    	cout << _year << ' ' << _month << ' ' << _day << ' ' << endl;
    }
    //判断某个日期是星期几,并打印出来
    //注意this指针不能由用户去传
    void Date::GetWeekDay()const
    {
    	const char* arr[7] = { "星期一","星期二","星期三","星期四","星期五","星期六","星期日" };
    	const Date tem(1, 1, 1900);
    	const int subret = (*this)-tem;
    	printf("%s\n", arr[(subret % 7)]);
    }
     
    //将 > 运算符进行重载
    bool Date ::operator> (const Date& date)const
    {
    	if (_year > date._year)
    	{
    		return true;
    	}
    	else if (_year == date._year && _month > date._month)
    	{
    		return true;
    	}
    	else if (_year == date._year && _month == date._month && _day > date._day)
    	{
    		return true;
    	}
    	return false;
    }
    //将 =运算符进行重载
    bool Date:: operator==(const Date& date)const
    {
    	if (date._day == _day && date._month == _month && date._year == _year)
    	{
    		return true;
    	}
    	return false;
    }
    //在逻辑上我们只需定义出大于(或小于)和等于的判断函数,剩余的判断函数我们就可以通过复用的方式简化代码书写
    bool Date :: operator>= (const Date& date)const
    {
    	if ((*this) > date || (*this) == date)
    	{
    		return true;
    	}
    	return false;
    }
     
    bool Date :: operator < (const Date& date)const
    {
    	if ((*this) >= date)
    	{
    		return false;
    	}
    	return true;
    }
     
    bool Date :: operator<=(const Date& date)const
    {
    	if ((*this) > date)
    	{
    		return false;
    	}
    	return true;
    }
    bool Date:: operator!= (const Date& date)const
    {
    	if ((*this) == date)
    	{
    		return false;
    	}
    	return true;
    }
     
    //一组日期+(-)整数的操作和+=(-=)整数的操作
    Date& Date::operator+=(const int day)
    {
    	if (day < 0)
    	{
    		(*this) -= (-day);
    		return (*this);
    	}
    	_day += day;
    	while (_day > GetMonthday(_month))
    	{
    		if (_month < 12)
    		{
    			_day -= GetMonthday(_month);
    			_month++;
    		}
    		else
    		{
    			_day -= GetMonthday(_month);
    			_year++;
    			_month = 1;
    		}
    	}
    	return (*this);
    }
    Date Date::operator+(const int day)const
    {
    	Date tem(*this);
    	tem += day;
    	return tem;
    }
     
    Date& Date::operator-=(const int day)
    {
    	if (day < 0)
    	{
    		(*this) += (-day);
    		return (*this);
    	}
    	_day -= day;
    	while (_day <= 0 )
    	{
    		if (_month > 1)
    		{
    			_month--;
    			_day += GetMonthday(_month);
    		}
    		else
    		{
    			_year--;
    			_month = 12;
    			_day += GetMonthday(_month);
    		}
    	}
    	if (_year <= 0)
    	{
    		cout << "operation invalued" << endl;
    		exit(0);
    	}
    	return (*this);
    }
    Date Date::operator-(int day)const
    {
    	Date tem(*this);
    	tem -= (day);
    	return tem;
    }
    Date& Date ::operator=(const Date& date)
    {
    	if (this != &date)
    	{
    		_day = date._day;
    		_month = date._month;
    		_year = date._year;
    	}
     
    	return (*this);
    }
     
    //一组前置++(--)和后置++(--)的重载
    Date& Date ::operator++()             //实现日期类的前置++
    {
    	(*this) += 1;
    	return (*this);
    }
    Date Date ::operator++(int)           //实现日期类的后置++
    {
    	Date tem(*this);
    	(*this) += 1;
    	return tem;
    }
    Date& Date:: operator--()             //实现日期类的前置--
    {
    	(*this) -= 1;
    	return (*this);
    }
    Date Date:: operator--(int)           //实现日期类的后置--
    {
    	Date tem(*this);
    	(*this) -= 1;
    	return tem;
    }
     
    //实现时期相减的操作符重载
    int Date::operator-(const Date& date)const
    {
    	int count = 0;
    	Date min;
    	if ((*this) < date)
    	{
    		min = (*this);
    		while (min != date)
    		{
    			min++;
    			count++;
    		}
    		return -count;
    	}
    	else
    	{
    		min = date;
    		while (min != (*this))
    		{
    			min++;
    			count++;
    		}
    		return count;
    	}
    }

    到此,关于“C++类中const修饰的成员函数及日期类怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI