关于类的静态成员与友元

一、静态成员

        首先,总体来说静态成员也是类的成员,受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指针便意味着静态成员函数无法访问任何非静态的成员变量,因此,对于静态成员函数来说,它更像用于专门的去访问静态成员变量。

二、友元

        友元总的来说,虽然提供了一种突破封装的方式,提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

        使用友元需要注意的是,友元关系是单向的,没有交换性,和传递性,也不能继承。这种关系通俗一点来说,就跟某些人的一厢情愿一样,你把别人当朋友,跟他掏心掏肺,可是别人惹都不惹你,不存在互相交换资源的可能,而且他的朋友不是你的朋友,朋友关系不能传递,那么更别说继承了。

        友元分两类,声明时都要加上friend

        1.友元函数

        友元函数的应用场景不多,但也很关键,如果各位动手编写过类,在重载流符号”>>“与”<<“时,相信都有过为难,既想访问类的成员变量,可是又因为this指针不能显式声明导致重载的奇奇怪怪,这个时候用上友元函数,整个人都凉快了许多:
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;
};

        代码第三行,便是友元类的声明。友元类没有太多的注意点,主要特性就是友元特性。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值