C++ 初阶 | 类和对象易错知识点(上)
目录
0.引言
1.访问限定符
2.域
3.类的实例化和声明
4.this指针
5.构造函数(自动执行)
6.拷贝构造
7.运算符重载
8.日期类的实现
9.总结
0.引言
今天,小邓儿和大家分享一下,C++在类和对象中的易错知识点🤭🤭🤭。
1.访问限定符
🚩struct若是没有访问限定符,默认是public;
🚩class若是没有限制访问,默认是private
2.域
☆☆☆类域:解决和类和类之间的命名冲突问题;
☆☆☆命名空间域:解决全局函数/变量/类型的命名冲突;
tip:上面两种类域不影响生命周期,全局域、局部域影响生命周期。
3.类的实例化和声明
👇类的声明:
class Date
{...
private:
int _year; //这种情况,是声明,不申请空间。类实例化对象时才申请空间。
int _month;
int _day;
...
}
👇类实例化对象:
Date d1; //类实例化对象,会为d1申请空间
tip:类实例化对象时,只存成员变量,不存成员函数地址。
4.this指针
🚩this指针在形参和实参的位置不可以显式使用,在函数体内部可以显式使用
tip:空指针解引用是运行错误(编译错误---语法错误;运行错误---和语法无关)
5.构造函数(自动执行)
6.拷贝构造
❀1.拷贝构造第一个参数必须是当前对象的引用&(取别名),若是传值传参会形成无穷递归
❀2.若未显示定义拷贝构造函数,编译器会自动生成拷贝函数,对内置类型的成员变量进行浅拷贝。
❀3.浅 /(值)拷贝:不指向资源(编译器可以自动生成)
❀4.一般来言,若要显示地写析构函数并释放空间,就要显示地写拷贝函数
7.运算符重载
🚩形式: 类型名 operator 运算符 eg: bool operator == ()
tip:当运算对象,经过运算符重载函数后,不改变本身,尽量用(const 类名 & 对象名)【注:1.const权限的扩大问题; 2.&减少使用拷贝函数,提升效率😄】
bool Date:: operator==(const Date &d1,const Date& d2)
{
return d1. _year == d2._year && d1._month == d2._month && d1._day == d2._day;
};
tip:在成员函数中用运算符重载,少一个参数 👇
bool Date:: operator==(const Date& d)
{
return _year == d._year && _month == d._month && _day == d._day;
};
🚩有五个运算符不能重载
.* :: sizeof ?: .
8.日期类的实现
🚩 test.cpp
#include"Date.h"
void test_01()
{Date d1(2025, 5, 18);Date d2(d1);Date d3 = d1;d1.Print();d2.Print();d3.Print();d3 += 100; //d3+=100天d3.Print();Date d4 = d2 + 100;d2.Print();d4.Print();
}
void test_02()
{Date d1(1024, 2, 29);Date d3(2028, 2, 14);/*Date d2=d1-10000;d1 -= 10000;*///++d1;//d1.Print();//d1.Print();/*d2.Print();*//*d3.Print();*/int t=d1-d3;cout << "相差:" << t << "天\n";
};
void test_03()
{Date d1(2025, 5, 20);Date d2(2040, 8, 3);if (d1 > d2)cout << "d1>d2" << endl;if (d1 == d2)cout << "d1==d2" << endl;if (d1 >= d2)cout << "d1>=d2" << endl;if (d1 < d2)cout << "d1<d2" << endl;if (d1 <= d2)cout << "d1<=d2" << endl;};
int main()
{ //test_01();test_02();//test_03();return 0;
}
🚩Date.h
#pragma once
#include<iostream>
using namespace std;
class Date{
public:// 获取某年某月的天数int GetMonthDay(int year, int month);// 全缺省的构造函数Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;};// 拷贝构造函数d2(d1)Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}//打印void Print()const; //防止出现权限扩大问题【注:只要是不改变调用对象的函数,都建议加const()】// 赋值运算符重载 d2 = d3 -> d2.operator=(&d2, d3)Date& operator=(const Date& d);// 析构函数~Date() { cout << "~Date()\n"; };// 日期+=天数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);private:int _year;int _month;int _day;};
🚩Date.cpp
#include"Date.h"//打印
void Date::Print()const
{cout << _year << "/" << _month << "/" << _day<<endl;
}// 获取某年某月的天数
int Date::GetMonthDay(int year, int month)
{int MonthDay[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };if ((month == 2) && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) //month == 2不要写成month = 2{return 29;}else{return MonthDay[month - 1];}
};// 赋值运算符重载 d2 = d3 -> d2.operator=(&d2, d3)
Date& Date::operator=(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;return *this;
};// 日期+=天数
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)) //tip:while 不能写成if:// 原因:if 语句只会检查一次条件,当天数较大,就会出错{_day -= GetMonthDay(_year, _month);++_month;if (_month > 12){_month =1; //不能写成==_year++;}}return *this;
};// 日期+天数
Date Date::operator+(int day) //不用&,为了不改变原来的day
{Date temp(*this); //使用 (*this) 初始化 temptemp += day;return temp;
};// 日期-=天数
Date& Date::operator-=(int day)
{_day -= day;while (_day < 0){if (_month == 1){--_year;_month = 12;}else //与if并列,若没有,当_month==1时会再减一个_month--_month;_day += GetMonthDay(_year, _month);}return *this;
};// 日期-天数
Date Date:: operator-(int day)
{Date temp(*this);temp -= day;return temp;
};// 前置++
Date& Date:: operator++()
{return *this += 1;
};// 后置++
Date Date:: operator++(int) //operator++(int)中的int是一种形式,无实际意义
{Date d(*this) ;return d+1; };// 后置--
Date Date ::operator--(int)
{Date d(*this);return d-1 ;
};// 前置--
Date& Date:: operator--()
{return *this -= 1;
};// >运算符重载
bool Date:: operator>(const Date& d)
{if (_year > d._year)return true;else if ((_year == d._year) && (_month > d._month))return true;else if( (_year == d._year )&& (_month == d._month) && (_day > d._day))return true;else 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);
};// 日期-日期 返回天数
int Date:: operator-(const Date& d)
{Date min(*this);Date max = d;int flag = 1;if (min> max){Date t=min;min = max;max = t ;flag = -1;}int n = 0;while (min < max){++min; //不能写成min++(本次代码中后置++不返回this本身)n++;}return n * flag;
};
9.总结
❤❤❤今天的分享就到这里啦,欢迎大家,评论留言哦❤❤❤