一、静态成员
首先,总体来说静态成员也是类的成员,受public、protected、private 访问限定符的限制
其次再分两类,声明时都要加上static:
1.静态成员变量
有时候某些特殊的场景下,比如你需要统计某个类出现的次数,使用普通的成员变量是无法完成的,曾经有一道面试题便是如此:
面试题:实现一个类,计算程序中创建出了多少个类对象。
你会怎么去完成?看看答案;
class A
{
public:
A() { ++_scount; }
A(const A& t) { ++_scount; }
~A() { --_scount; }
static int GetACount() { return _scount; }//静态成员函数
private:
static int _scount;
};
int A::_scount = 0;
void TestA()
{
cout << A::GetACount() << endl;
A a1, a2;
A a3(a1);
cout << A::GetACount() << endl;
}
看起来是不是让人有些拍案叫绝!没错,这便是类的静态成员变量,不过类的静态成员变量看起来很好使用,可你真的有注意到这几点吗?
1. 静态成员 为 所有类对象所共享 ,不属于某个具体的对象,存放在静态区2. 静态成员变量 必须在 类外定义 ,定义时不添加 static 关键字,类中只是声明3. 类静态成员即可用 类名 :: 静态成员 或者 对象 . 静态成员 来访问
2.静态成员函数
静态成员函数的定义如上文GetACout()函数,在此我就不冗余展示了。不过对于静态成员函数,我们需要注意的时,静态成员函数是没有隐藏的this指针的,没有this指针便意味着静态成员函数无法访问任何非静态的成员变量,因此,对于静态成员函数来说,它更像用于专门的去访问静态成员变量。
二、友元
友元总的来说,虽然提供了一种突破封装的方式,提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。
使用友元需要注意的是,友元关系是单向的,没有交换性,和传递性,也不能继承。这种关系通俗一点来说,就跟某些人的一厢情愿一样,你把别人当朋友,跟他掏心掏肺,可是别人惹都不惹你,不存在互相交换资源的可能,而且他的朋友不是你的朋友,朋友关系不能传递,那么更别说继承了。
1.友元函数
class Date
{
friend ostream& operator<<(ostream& _cout, const Date& d);
friend istream& operator>>(istream& _cin, Date& d);
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& out, const Date& d)
{
out << d._year << "-" << d._month << "-" << d._day;
return out;
}
istream& operator>>(istream& in, Date& d)
{
in >> d._year;
in >> d._month;
in >> d._day;
return in;
}
看过之后,那么需要注意的点又来了:
1.友元函数可访问类的私有和保护成员,但不是类的成员函数
2.友元函数不能用const修饰
3.友元函数可以在类定义的任何地方声明,不受类访问限定符限制4.一个函数可以是多个类的友元函数5.友元函数的调用与普通函数的调用原理相同
2.友元类
class Time
{
friend class Date; // 声明日期类为时间类的友元类
public:
Time(int hour = 0, int minute = 0, int second = 0)
: _hour(hour)
, _minute(minute)
, _second(second)
{}
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)
{}
void SetTimeOfDate(int hour, int minute, int second)
{
// 直接访问时间类私有的成员变量
_t._hour = hour;
_t._minute = minute;
_t._second = second;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
代码第三行,便是友元类的声明。友元类没有太多的注意点,主要特性就是友元特性。