一,类的静态成员及友元
(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关键字 声明一个友元
使用 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 谢谢>
出处:
http://blog.csdn.net/meiwm
本文为原创,本文版权归作者所有。欢迎转载,但请务必保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。
-