static成员:
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数
代码示例:
class A
{
public:
A()
{
++_count;
}
~A()
{
}
A(const A& a)
{
_a = a._a;
++_count;
}
static int Getcount()
{
return _count;
}
private:
int _a;
static int _count;
};
int A::_count = 0;
int main()
{
A a;
A a2;
A a3(a2);
cout << a.Getcount() << endl;
system("pause");
return 0;
}
特性:
- 静态成员为所有类对象所共享,不属于某个具体的实例
- 静态成员变量必须在类外定义,定义时不添加static关键字
- 类静态成员即可用类名::静态成员或者对象.静态成员来访问
- 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
- 静态成员和类的普通成员一样,有public、protected、private3种访问级别,可以具有返回值
友元函数:
没办法将operator<<重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置.this指针默认是第一个参数也就是左操作数了.但是实际使用中cout需要是第一个形参对象,才能正常使用.所以我们要将operator<<重载成全局函数.但是这样的话,又会导致类外没办法访问成员,那么这里就需要友元来解决
不符常理的cout:
ostream& operator<<(ostream& _cout)
{
_cout << _year << "-" << _month << "-" << _day;
return _cout;
}
int main()
{
Date d;
d << cout;
Date d2(1996, 7, 28);
d2 << cout;
system("pause");
return 0;
}
代码示例:
友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字
class Date
{
friend ostream& operator<<(ostream& _cout,const Date& d);
public:
Date(int year = 1900, int month = 1,int day = 1) :_year(year), _month(month), _day(day)
{
}
~Date()
{
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& _cout,const Date& d)
{
_cout << d._year << "-" << d._month << "-" << d._day;
return _cout;
}
int main()
{
//Date d;
//d << cout;
Date d2(1996, 7, 28);
//d2 << cout;
cout << d2;
system("pause");
return 0;
}
说明:
- 友元函数可访问类的私有成员,但不是类的成员函数
- 友元函数不能用const修饰
- 友元函数可以在类定义的任何地方声明,不受类访问限定符限制
- 一个函数可以是多个类的友元函数
- 友元函数的调用与普通函数的调用和原理相同
友元类:
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员
特性:
- 友元关系是单向的,不具有交换性
- 友元关系不可传递
代码示例:
class Time
{
friend class Date;
public:
Time(int hour = 0, int minute = 0, int second = 0) :_hour(hour), _minute(minute), _second(second)
{
}
~Time()
{
}
Time(const Time& t)
{
_hour = t._hour;
_minute = t._minute;
_second = t._second;
}
void printTime()
{
cout << _hour << ":" << _minute << ":" << _second << endl;
}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1) :_year(year), _month(month), _day(day)
{
}
~Date()
{
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
void SetTime(int hour,int minute,int second)
{
_t._hour = hour;
_t._minute = minute;
_t._second = second;
}
void printDate()
{
cout << _year << "-" << _month << "-" << _day << " "
<< _t._hour << ":" << _t._minute << ":" << _t._second << endl;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
int main()
{
Date d(2019, 6, 30);
d.SetTime(15, 27, 30);
d.printDate();
system("pause");
return 0;
}
声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量
内部类:
代码示例:
class A
{
public:
class B
{
public:
void TestFun(const A& A)
{
cout << A.a << endl;
cout << A.b << endl;
}
};
private:
int a = 10;
int b = 10;
};
int main()
{
A::B b;
A a;
b.TestFun(a);
system("pause");
return 0;
}
特性:
- 内部类是外部类的友元类
- 外部类对内部类没有任何优越的访问权限
- 注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名
- sizeof(外部类)=外部类,和内部类没有任何关系
小练习①:
class Solution
{
class Sum
{
public:
Sum()
{
++_count;
_total+=_count;
}
Sum(const Sum& s)
{
++_count;
_total+=_count;
}
static void Reset()
{
_count=0;
_total=0;
}
static int Getsum()
{
return _total;
}
};
public:
int Sum_Solution(int n)
{
Sum::Reset();
Sum a[n];
return Sum::Getsum();
}
private:
static int _count;
static int _total;
};
int Solution::_count=0;
int Solution::_total=0;
小练习②:
注意事项:
<1>.主函数中的失败返回-1和结果只能用cout输出,用return牛客网会报错
<2>.循环输入使用while(cin>>year>>month>>day)
#include<iostream>
using namespace std;
bool isYear(int year)
{
if((year%4==0 && year%100!=0) || year%400==0)
{
return true;
}
return false;
}
int GetMonthDay(int year,int month)
{
int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isYear(year)==true)
{
days[2]=29;
}
return days[month];
}
bool NotTrueDate(int year,int month,int day)
{
if(year<0 || month<1 || month>12 || day<1 || day>GetMonthDay(year,month))
{
return true;
}
return false;
}
int TransDate(int year,int month,int day)
{
int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int totaldays=0;
if(isYear(year)==true)
{
days[2]=29;
}
for(int i=1;i<month;++i)
{
totaldays+=days[i];
}
totaldays+=day;
return totaldays;
}
int main()
{
int year,month,day;
while(cin>>year>>month>>day)
{
if(NotTrueDate(year,month,day)==true)
{
cout<<-1<<endl;
}
else
{
cout<<TransDate(year,month,day)<<endl;
}
}
return 0;
}