您的位置:首页 > 编程语言 > C语言/C++

C++中的static数据成员与static成员函数

2015-10-22 10:35 393 查看
本文要点:

1.static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在,每个static数据成员是与类关联的对象,并不与该类的对象相关联!

aka:[b]每个static数据成员可以看成是类的一个对象,而不与该类定义的对象有任何关系![/b]

[b]2.[b]static数据成员是存储在程序的静态存储区,而并不是在栈空间上[/b][/b]

[b]3.[b]不能对static数据成员在类内部进行初始化,要初始化的话必须在类外进行定义。[b]如果类中有多个static数据成员,static数据成员初始化的次序是按照static数据成员在类中的声明次序进行初始化的,初始化了之后,就可以使用static数据成员了,我们可以通过作用域操作符从类直接调用static数据成员,或者通过对象,引用,或指向该类类型对象的指针间接调用(这种情况下static数据成员必须是public的访问权限,如果定义在private访问权限下是不行的)。[b]const int 型的static成员便可以在类定义体内部进行初始化。记住一定只能是const int型的,换成const string ,double都不行的。[/b][/b][/b][/b]

[b][b][b]4.[b]static数据成员的类型可以是该成员所属的类类型,非static数据成员被限定为其自生类对象的指针或引用。[/b][/b][/b][/b]

[b][b][b]5.[b]static成员是类的组成部分并不是任何对象的组成部分,因此,static成员函数没有this指针。我们知道,一般而言,类中的成员函数具有一个附加的隐含实参,即指向该类对象的一个指针。这个隐含实参命名为this。因为static成员函数不是任何对象的组成部分,所以static成员函数就没有this形参了。由于成员函数声明为const说明该成员函数不会修改该成员函数所属的对象,所以static成员函数不能声明为const。为什么呢?因为static成员函数不是任何对象的组成部分。static成员函数可以直接访问所属类的static成员,但是不能直接使用非static成员函数!也不能访问static const 类型的成员![/b][/b][/b][/b]

[b][b][b]6.[b][b]私有的静态成员只能通过类的静态成员函数进行修改 ,公有的静态成员可以直接进行修改,访问方式可以obj.j或者Test::j [/b] [/b][/b][/b][/b]

本文转载,在此感谢。
http://www.cnblogs.com/gysm/archive/2011/09/16/2179277.html http://blog.csdn.net/naturebe/article/details/7554589
C++类中谈到static,我们可以在类中定义static成员,static成员函数!C++primer里面讲过:static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在,每个static数据成员是与类关联的对象,并不与该类的对象相关联!这句话可能比较拗口,其实可以这么理解:每个static数据成员可以看成是类的一个对象,而不与该类定义的对象有任何关系!下面我们就来具体看看类中的static数据成员!

谈到数据成员,我们最先想到的应该是怎么去定义一个static数据成员,static数据成员是存储在程序的静态存储区,而并不是在栈空间上。既然是static数据成员,所以关键字static是必不可少的,例如:

1 static.h文件
2 #include  <iostream>
3 #include  <string>
4 using namespace std;
5 class Person
6 {
7 private:
8     string name;
9     static int age;
10 public:
11     Person(const string&nm):name(nm)
12     {}
13     void Print()
14     {
15         cout<<name<<" is "<<age<<endl;
16     }
17 };
18 int Person::age=20;
19
20 static.cpp文件
21
22 #include "stdafx.h"
23 #include "static.h"
24 #include <iostream>
25 using namespace std;
26
27 int _tmain(int argc, _TCHAR* argv[])
28 {
29     Person person("tom");
30     person.Print();
31     cout<<endl;
32     return 0;
33 }


Person类中定义了一个static数据成员age,注意在类中不能对static数据成员在类内部进行初始化,要初始化的话必须在类外进行定义!注意,static数据成员不是通过类构造函数进行初始化的!如上面的代码所示:在类外定义int Person::age=20;这里前面就不要再加static了。如果类中有多个static数据成员,static数据成员初始化的次序是按照static数据成员在类中的声明次序进行初始化的,初始化了之后,就可以使用static数据成员了,我们可以通过作用域操作符从类直接调用static数据成员,或者通过对象,引用,或指向该类类型对象的指针间接调用(这种情况下static数据成员必须是public的访问权限,如果定义在private访问权限下是不行的)。

说到static数据成员,有一种情况不得不提,那就是特殊的const static成员。如上面所述,类的static成员,像普通数据成员一样,不能在类的定义体中进行初始化。只能在类外进行初始化。const int 型的static成员便可以在类定义体内部进行初始化。记住一定只能是const int型的,换成const string ,double都不行的。看下面这段代码:

static.h头文件
#include  <iostream>
#include  <string>
using namespace std;
class Person
{
private:
string name;
static const int age=20;
static string address;
public:
Person(const string&nm):name(nm)
{}
static string Address()
{
return address;
}
void Print()
{
cout<<name<<" is "<<age ;
}
};
string Person::address="Beijing";

static.cpp文件

#include "stdafx.h"
#include "static.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
Person person("tom");
person.Print();
cout<<" and live in "<<person.Address();
cout<<endl;
return 0;
}


只有age才能在类定义体内进行初始化,address是不行的。这段代码不能在VC6.0上运行的,它不支持。在vs2008上可以运行。在C++Primer里面有一段注解:const static数据成员在类的定义体中进行了初始化后,还必须在类的定义体之外进行定义。其实这是可要可不要的。上面的代码就没有这段代码实现,其实加上去也是可以的,没有关系。还有一点,static数据成员的类型可以是该成员所属的类类型,非static数据成员被限定为其自生类对象的指针或引用。例如:类定义位如下的情况:

class Person
{
private:
string name;
static const int age=20;
static string address;
static Person person1;
Person *person2;
Person person3;
public:
Person(const string&nm):name(nm)
{}
static string Address()
{
return address;
}
void Print()
{
cout<<name<<" is "<<age ;
}
};


如果没有定义person3,则能够顺利通过编译,但是加上了person3就不能通过编译了!

说完了static成员后,我们再来看看static成员函数,static成员是类的组成部分并不是任何对象的组成部分,因此,static成员函数没有this指针。我们知道,一般而言,类中的成员函数具有一个附加的隐含实参,即指向该类对象的一个指针。这个隐含实参命名为this。因为static成员函数不是任何对象的组成部分,所以static成员函数就没有this形参了。由于成员函数声明为const说明该成员函数不会修改该成员函数所属的对象,所以static成员函数不能声明为const。为什么呢?因为static成员函数不是任何对象的组成部分。static成员函数可以直接访问所属类的static成员,但是不能直接使用非static成员函数!也不能访问static const 类型的成员!在上面的代码中static string Address()函数中如果是return name或者是return age都不行! 好吧,就说这么些吧,如果哪里有不当之处,还请各位指正!

下面用一个简单的程序加以理解

[cpp] view plaincopyprint?

#include <iostream>

#include <string>

using namespace std;

class Test

{

public:

static int j;

static void init();//init定义为static 或非static都可以修改static成员i的值

static int revise_i(int x);

int get_i();

//由于没有this指针,static成员函数不能访问对象的非static成员,用static输出k是非法的

private:

static int i;

int k;

const static int r = 1; //只有const static 成员在类定义时初始化,不确切,看上篇说的

//若将上面的i直接初始化,编译时报错

};

//外部定义时不能再标示static

int Test::i=0; //very important:外部定义(正好一次),之后i只能通过init修改

int Test::j=5; //j为public,之后可以直接访问和修改

void Test::init()

{

i=10;

}

int Test::get_i()

{

return i;

}

int Test::revise_i(int x)

{

i = x;

return i;

}

int main()

{

Test obj;

cout << obj.get_i() << endl; //通过

obj.init();//私有的静态成员只能通过类的静态成员函数进行修改

cout << obj.get_i() << endl;

cout << Test::j << endl;

obj.j = 15; //[b]//私有的静态成员只能通过类的静态成员函数进行修改 ,公有的静态成员可以直接进行修改,访问方式可以obj.j或者Test::j [/b]

Test::revise_i(555);

cout << "after revise_i, i = " << obj.get_i() << endl;

cout << Test::j << endl;

system("pause");

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: