Java面试宝典:MongoDB实战技巧 作者:忆遂愿
https://cloud.tencent.com/developer/article/2466159?shareByChannel=link
文章对 MongoDB 知识的全面阐述,质量很高。从基本概念、Java 驱动使用、数据操作、安全性能问题与解决、数据一致性事务处理,到数据模型设计、技术集成和存储图片优势等方面讲解详细、条理清晰,体现出作者深入的理解。
要实现一个日期类我们先考虑一下他有什么成员?
必须有的:年、月、日
对于构造函数,由于 Date 类的成员类型均为内置类型,虽然编译器在某些情况下能够自动生成默认构造函数,但为了代码的清晰性和可控性,我们可以显式地编写一个全缺省的构造函数。如下所示:
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
通过这个构造函数,我们能够方便地创建 Date 类对象,并在创建时为年、月、日成员赋予初始值。如果在创建对象时没有提供参数,对象将被初始化为默认的日期(例如 0 年 1 月 1 日)。
接下来我们再来考虑下日期类一般会有什么方法?
考虑到成员都是内置类型,不存在需要手动释放的资源,因此不需要显式地编写析构函数。编译器生成的默认析构函数足以处理这类情况,它会自动执行一些基本的清理工作,如释放对象占用的内存空间等。
在拷贝构造函数方面,编译器会自动提供一个默认的拷贝构造函数。这个默认的拷贝构造函数能够完成简单的成员变量值的拷贝操作,对于 Date 类这种成员为内置类型的情况,通常能够满足基本需求。然而,如果我们希望自定义拷贝构造函数的行为,也可以显式地编写。其实现如下:
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
拷贝构造函数的名称与类名相同,它接受一个常量引用类型的参数,该参数为需要拷贝的源对象。在函数体内,将源对象的成员变量值逐一赋值给当前对象的相应成员变量,从而实现对象的拷贝。
日期类通常需要一个方法来获取指定月份的天数。因为不同月份的天数有所不同,并且还需要考虑闰年的情况。以下是获取某个月具体天数的函数实现:
int Date::GetMonthDay(int year, int month)
{
static int MonthDay[13] = { -1,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;
}
else
{
return MonthDay[month];
}
}
这里我们使用一个静态数组来存储每个月的天数信息,将数组长度设置为 13,以便数组下标能够与月份直接对应(其中下标 0 处的值 -1 可作为一种特殊标记或占位,无实际月份对应意义)。在函数中,首先判断是否为闰年的二月,如果是,则返回 29 天;否则,直接返回数组中对应月份的天数。
编译器会自动生成默认的赋值运算符重载函数,但有时我们可能需要自定义其行为。显式实现赋值运算符重载函数时,需要注意一些关键要点。以下是其实现代码:
Date& Date::operator=(const Date& d)
{
//检查自赋值
if (this == &d)
{
return *this;
}
_year = d._year;
_month = d._month;
_day = d._day;
return *this;
}
其返回值类型为类类型的引用,这样可以实现连续赋值操作(例如:a = b = c;)。形参为一个常量引用类型的参数,表示要赋值的源对象。在函数体中,首先进行自赋值检查,如果当前对象与源对象相同(即this指针指向的地址与源对象地址相同),则直接返回当前对象,避免不必要的赋值操作。然后,将源对象的成员变量值赋值给当前对象的成员变量,并最终返回当前对象的引用。
除了上述提到的运算符重载外,日期类还可能涉及其他运算符的重载,如日期的比较运算符(大于、小于、等于等)、日期的加减运算(例如计算两个日期之间的间隔天数,或者在某个日期上增加或减少一定天数得到新的日期)等。这些运算符重载的核心思想是复用已有的函数或方法,以提高代码的简洁性和可维护性。虽然这里不一一详细说明,但在实际实现中,可以根据具体的需求和逻辑进行设计与编写。
为了方便日期类对象的输入和输出操作,我们可以重载输入流运算符>>和输出流运算符<<。需要注意的是,它们并非日期类的成员函数,而是日期类的友元函数。友元函数的特点是可以访问类的所有成员,但由于它不属于类的成员函数,所以没有隐藏的this指针,因此需要传递两个参数。以下是其实现代码:
friend ostream& operator<<(ostream& os, Date& d)
{
os << d._year << "/" << d._month << "/" << d._day << endl;
return os;
}
friend istream& operator>>(istream& is, Date& d)
{
is >> d._year >> d._month >> d._day;
return is;
}
需要注意的是他们不是日期类的成员函数,而是日期类的友元函数,返回值类型前面加了关键字friend来修饰,注意友元函数虽然可以访问类的所有成员,但是由于他本身不是类的成员函数也就没有了隐藏的this指针,所以需要传两个参数.
#pragma once
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 0, int month = 0, int day = 0);
// 拷贝构造函数
// d2(d1)
Date(const Date& d);
// 获取某年某月的天数
int GetMonthDay(int year, int month);
// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& operator=(const Date& d);
// 日期+=天数
Date& operator+=(int day);
// 日期+天数
Date operator+(int day);
// 日期-天数
Date operator-(int day);
// 日期-=天数
Date& operator-=(int day);
// 前置++
Date& operator++();
// 后置++
Date operator++(int);
// 后置--
Date operator--(int);
// 前置--
Date& operator--();
// >运算符重载
bool operator>(const Date& d);
// ==运算符重载
bool operator==(const Date& d);
// >=运算符重载
bool operator >= (const Date& d);
// <运算符重载
bool operator < (const Date& d);
// <=运算符重载
bool operator <= (const Date& d);
// !=运算符重载
bool operator != (const Date& d);
// 日期-日期 返回天数
int operator-(const Date& d);
void print()const;
// 析构函数(日期类无需清理资源,析构函数不必显示写)
//~Date()
//{
//cout << "~Date()" << endl;
//}
friend ostream& operator<<(ostream& os, Date& d)
{
os << d._year << "/" << d._month << "/" << d._day << endl;
return os;
}
friend istream& operator>>(istream& is, Date& d)
{
is >> d._year >> d._month >> d._day;
return is;
}
private:
int _year, _month, _day;
};
#include"Date.h"
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& Date::operator=(const Date& d)
{
//检查自赋值
if (this == &d)
{
return *this;
}
_year = d._year;
_month = d._month;
_day = d._day;
return *this;
}
int Date::GetMonthDay(int year, int month)
{
static int MonthDay[13] = { -1,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;
}
else
{
return MonthDay[month];
}
}
void Date::print()const
{
cout << _year << "年" << _month << "月" << _day << "日" << endl;
}
// >运算符重载
bool Date::operator>(const Date& d)
{
if (_year > d._year)
{
return true;
}
else if (_year == d._year)
{
if (_month > d._month)
{
return true;
}
else if (_month == d._month)
{
if (_day > d._day)
{
return true;
}
}
}
return false;
}
// ==运算符重载
bool Date::operator==(const Date& d)
{
return _year == d._year && _month == d._month && _day == d._day;
}
// >=运算符重载
bool Date::operator >= (const Date& d)
{
return (*this > d || *this == d);
}
// <运算符重载
bool Date::operator < (const Date& d)
{
return !(*this >= d);
}
// <=运算符重载
bool Date::operator <= (const Date& d)
{
return !(*this > d);
}
// !=运算符重载
bool Date::operator != (const Date& d)
{
return !(*this == d);
}
// 日期+=天数
Date& Date::operator+=(int day)
{
_day += day;
while (_day > GetMonthDay(_year, _month))
{
_month++;
if (_month == 13)
{
_year++;
_month = 1;
}
_day -= GetMonthDay(_year, _month);
}
return *this;
}
// 日期+天数
Date Date::operator+(int day)
{
Date tmp;
tmp += day;
return tmp;
}
// 日期-天数
Date Date::operator-(int day)
{
Date tmp;
tmp -= day;
return tmp;
}
// 日期-=天数
Date& Date::operator-=(int day)
{
_day -= day;
while (_day <= 0)
{
_month--;
if (_month == 0)
{
_month = 12;
_year--;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
// 前置++
Date& Date::operator++()
{
*this += 1;
return *this;
}
// 后置++
Date Date::operator++(int)
{
Date tmp(*this);
*this += 1;
return tmp;
}
// 后置--
Date Date::operator--(int)
{
Date tmp(*this);
*this -= 1;
return tmp;
}
// 前置--
Date& Date::operator--()
{
*this -= 1;
return *this;
}
// 日期-日期 返回天数
int Date::operator-(const Date& d)
{
Date max(*this);
Date min(d);
int flag = 1;
int count = 0;
if (*this < d)
{
flag = -1;
max = d;
min = *this;
}
while (min < max)
{
min++;
count++;
}
return count * flag;
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。