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

C++ 类中的静态变量和静态成员函数(转)

2011-10-25 19:08 288 查看

静态数据成员:

下面看一个例子:

#include <iostream.h>

class Point

{

public:

void output()

{

}

static void init()

{

}

};

void main( void )

{

Point pt;

pt.init();

pt.output();

}

这样编译是不会有任何错误的。

下面这样看

#include <iostream.h>

class Point

{

public:

void output()

{

}

static void init()

{

}

};

void main( void )

{

Point::output();

}

这样编译会处错,错误信息:illegal call of non-static member function,为什么?

因为在没有实例化一个类的具体对象时,类是没有被分配内存空间的。

好的再看看下面的例子:

#include <iostream.h>

class Point

{

public:

void output()

{

}

static void init()

{

}

};

void main( void )

{

Point::init();

}

这时编译就不会有错误,因为在类的定义时,它静态数据和成员函数就有了它的内存区,它不属于类的任何一个具体对象。

好的再看看下面的例子:

#include <iostream.h>

class Point

{

public:

void output()

{

}

static void init()

{

x = 0;

y = 0;

}

private:

int x;

int y;

};

void main( void )

{

Point::init();

}

编译出错:

illegal reference to data member 'Point::x' in a static member function

illegal reference to data member 'Point::y' in a static member function

在一个静态成员函数里错误的引用了数据成员,

还是那个问题,静态成员(函数),不属于任何一个具体的对象,那么在类的具体对象声明之前就已经有了内存区,

而现在非静态数据成员还没有分配内存空间,那么这里调用就错误了,就好像没有声明一个变量却提前使用它一样。

也就是说在静态成员函数中不能引用非静态的成员变量。

好的再看看下面的例子:

#include <iostream.h>

class Point

{

public:

void output()

{

x = 0;

y = 0;

init();

}

static void init()

{

}

private:

int x;

int y;

};

void main( void )

{

Point::init();

}

好的,这样就不会有任何错误。这最终还是一个内存模型的问题,

任何变量在内存中有了自己的空间后,在其他地方才能被调用,否则就会出错。

好的再看看下面的例子:

#include <iostream.h>

class Point

{

public:

void output()

{

}

static void init()

{

x = 0;

y = 0;

}

private:

static int x;

static int y;

};

void main( void )

{

Point::init();

}

编译:

Linking...

test.obj : error LNK2001: unresolved external symbol "private: static int Point::y" (?y@Point@@0HA)

test.obj : error LNK2001: unresolved external symbol "private: static int Point::x" (?x@Point@@0HA)

Debug/Test.exe : fatal error LNK1120: 2 unresolved externals

执行 link.exe 时出错.

可以看到编译没有错误,连接错误,这又是为什么呢?

这是因为静态的成员变量要进行初始化,可以这样:

#include <iostream.h>

class Point

{

public:

void output()

{

}

static void init()

{

x = 0;

y = 0;

}

private:

static int x;

static int y;

};

int Point::x = 0;

int Point::y = 0;

void main( void )

{

Point::init();

}

在静态成员数据变量初始化之后就不会出现编译错误了。

再看看下面的代码:

#include <iostream.h>

class Point

{

public:

void output()

{

}

static void init()

{

x = 0;

y = 0;

}

private:

static int x;

static int y;

};

void main( void )

{

}

编译没有错误,为什么?

即使他们没有初始化,因为我们没有访问x,y,所以编译不会出错。

后记————今天在增加模块checkemailaddr.c and checkemailaddr.h 文件的时候出现的编译连接错误。

static初始化的方法就是

int Point::x = 0;

int Point::y = 0;

link问题还没搞太清楚 在h文件里面定义static 而在cpp文件当中 初始化。

为什么在h文件当中初始化有问题。? 如果在哪初始化 没问题。类声明之后??

C++静态数据成员(static member)—静态成员的初始化不应该在头文件中,静态数据成员被类的所有对象共享、包括派生类的对象,在类中可以声明所属类自己的静态数据成员对象、不可以定义非静态数据成员对象,

2011-03-08 10:24:27| 分类:

C/C++程序设计_基 |字号 订阅

最终总结出静态数据成员的特点有::

1、静态数据成员仅仅在初始化时,不受访问权限的约束;

2、静态数据成员最好不要在.h文件中进行声明,而是放在.o文件中声明;

3、静态数据成员被类的所有对象所共享,包括类的派生类的所有对象;——即派生类和基类共享一个静态成员。

4、静态数据成员的类型可是所属类自己,即在一个类中可以声明该类自己的类型的静态成员对象,但是,不可以定义普通的成员对象,(指针可以)

5、在const成员函数中,可以修改static成员变量的值。普通成员变量的值,是不能修改的。

6、static成员函数只能访问static成员,不能访问非static成员,并且static成员函数不能定义为const函数。

详解

类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。

和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。注意::仅仅是初始化时不遵守public/protected/private的规则

同时,静态数据成员还具有以下特点:



1、静态数据成员的定义(初始化)不能在头文件中。

静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。

其定义方式与全局变量相同。举例如下:

xxx.h文件

class base{

private:

static const int _i; //声明,标准c++支持有序类型在类体中初始化,但vc6不支持。

};

xxx.cpp文件

const int base::_i=10; //定义(初始化)时不受private和protected访问限制.

注:不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。即使加上#ifndef #define #endif或者#pragma once也不行。


2、静态数据成员
被 类 的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。举例如下:

class base{

public :

static int _num; //声明

};

int base::_num=0; //静态数据成员的真正定义

class derived:public base{

};

main()

{

base a;

derived b;

a._num++;

cout<<"base class static data number _num is"<<a._num<<endl;

b._num++;

cout<<"derived class static data number _num is"<<b._num<<endl;

}

// 结果为1,2;可见派生类与基类共用一个静态数据成员。


3、静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为所属类类型的 指针或引用。举例如下:

class base{

public :

static base _object1; //正确,静态数据成员

base _object2; //错误

base *pObject; //正确,指针

base &mObject; //正确,引用 (这个正确吗?????)

};


4、静态数据成员的值在const成员函数中可以被合法的改变,而不破那个数据成员的值,不能在const成员函数中改变。

#include <iostream>

using namespace std;


class Student

{

private:

static int a;

int b;

public:

void change() const;

void setB(int b);

int getB();

static int getA();

};


void Student::change() const

{

a++; //这个可以,因为a是static成员变量。

b++; //不可以,因为是const函数

}

int Student::getA()

{

return a;

}

void Student::setB(int b)

{

this->b = b;

}

int Student::getB()

{

return b;

}

int Student::a = 5;


int main(int argc,char *argv[])

{

Student stu;

stu.setB(10);

stu.change();

cout<<Student::getA()<<endl;

cout<<stu.getB()<<endl;

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