C++快速入门 (十一) 类的其他内容

一,类的静态成员及友元

(1). 静态成员
由前面的介绍知道,一般的类成员只有实例化(后的对象名)才能访问,可以简单理解为 一般的类成员属于类的实例。而使用 关键字static 修饰的类成员可以通过类名直接访问。

class   Example
{
private  :
      static   int  sum;
public  :
      void  ShowSum()
    {
        cout <<   Example  ::sum << endl;
    }
      void  SetSum(   int   n  )
    {
          Example  ::sum +=   n  ;
    }
};
int Example ::sum = 0;  // 手动设置初始值

int   _tmain  ( int   argc,   _TCHAR*   argv  [])
{
      Example  *exA =   new   Example  ();
      Example  *exB =   new   Example  ();
   
    exA->ShowSum();    // 10
    exA->SetSum(200);
    exB->ShowSum();    // 200
      return  0;
};

通过代码可以知道:
  • 静态成员通过 类名 + 作用域操作符( :: ), 来访问。既可以简单理解为类的静态成员属于类本身。
  • 类的静态成员不能直接访问该类的非静态成员。
  • 理论上类的静态成员在该类第一次被加载时初始化, 并且只被初始化一次。
  • 类的静态成员变量为所有类共享 ( 和非静态成员的主要区别 )。
  • C++中没有静态构造函数(C#穿越过来的尤其要注意),所以需要用户手动设置静态变量的初始值。并且要在 main函数调用 之前。
  • 为私有静态成员变量设置初始值时,可以通过作用域操作符直接访问。但其他地方是不允许的。

(2). 友元
友元的作用是 让某个指定的非该类成员函数访问一个这个类的私有成员(单向公开)。这显然违背了面向对象原则。所以这里只是简单介绍。
使用 friend关键字 声明一个友元 

class  Example
{
     friend class FriendEx ;
     friend  void FriendFun();
private :
     int num;
public :
    Example( int  n): num(  n ) { };
};
class FriendEx
{
public :
     void Show()
    {
         Example ex(10);
        cout <<  ex.num << endl;
    }
};
void FriendFun()
{
     Example ex(20);
    cout <<  ex.num << endl;
}
int  main ()
{
     FriendEx fr;
    fr.Show();
     FriendFun();
     return 0;
};

友元不仅可以是 类或成员函数,甚至可以是非成员函数。


二,类的内存结构和this指针

(1). 类的内存结构
需要知道的是:
  • 当一个类为空类时,该类的大小为 1字节,当一个类拥有非静态成员变量时类大小就是成员变量大小之和。并且是连续存放的。
  • 非静态成员函数被编译后会转换为全局函数,并且编译器会为其加入一个叫做 this 的指针类型参数该指针指向其所在类的对象地址。
  • 静态成员变量被统一放在一个叫做静态存储区的内存区域。
可以通过下面的示例观察到。

class   Example
{
public  :
      int  a;
      int  b;
      static   int  staticNum;
    Example():a(10),b(10) { };
      void  ShowThis()
    {
        cout <<   "this: "  <<   this  << endl;
    };
      static   void  showStaticNum()
    {
        cout <<   "staticNum="  << staticNum << endl;
    };
};
int   Example  ::staticNum = 0;
int   _tmain  (  int   argc,   _TCHAR*   argv  [])
{
      Example  exA,exB;
    cout <<   "Example size = "  <<   sizeof  (   Example  ) << endl;   // 8
      Example  *pExA = &exA;
      Example  *pExB = &exB;
    cout <<   "Example address: exA = "     << pExA << endl;
    cout <<   "Example address: exA.this = "  ;
    pExA->ShowThis();
    cout << endl;
    cout <<  "Example address: exB = "    << pExB << endl;   // 两个地址相同
    cout <<   "Example address: exB.this = "  ;
    pExB->ShowThis();

    cout << endl;
      int  *pExAa = &(pExA->a);
      int  *pExAb = &(pExA->b);
      int  *pExAc = &(   Example  ::staticNum);
    cout <<   "Example address: exA.a = "  << pExAa << endl;
    cout <<   "Example address: exA.b = "  << pExAb << endl; 
    cout <<   "Example address: exA.c = "  << pExAc << endl;

      return  0;
};


(2). this 指针
前边说过 成员函数(这章所有成员函数都是指非静态成员函数,静态成员函数没有this)编译后会变成全局函数,并不和类存放在一起。和类存放在一起的只有成员变量(到目前为止),当在一个类的成员函数体内调用该类的其他成员时。就要通过 this指针 加 偏移量来访问。即便你没有显式声明,编译时也会自动添加 this。

(3). 常量(coust)this
类成员函数签名后加 关键字 coust ,会 使t通过 his访问的类成员均不能被修改。

class   Example
{
public  :
      int  x;
      int GetInt () const
    {
          //x = 70;   error;
          return  x;
    }
};




-

<原创文章 转载请注明出处 http://blog.csdn.net/meiwm 谢谢>


作者:meiwm
出处: http://blog.csdn.net/meiwm
本文为原创,本文版权归作者所有。欢迎转载,但请务必保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。

-


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值