首先,建立一个win32控制台程序
#include <iostream.h>
class Point
{
public:
void output()
{
cout<<"Hello word!"<<endl;
}
static void init()
{
cout<<"Hello!"<<endl;
}
};
void main()
{
Point pt;
pt.output();
pt.init();
}
编译运行,上述程序是可行的。现在,在main函数中,使用作用域来直接调用成员函数
#include <iostream.h>
class Point
{
public:
void output()
{
cout<<"Hello word!"<<endl;
}
static void init()
{
cout<<"Hello!"<<endl;
}
};
void main()
{
/*Point pt;
pt.output();
pt.init();*/
Point::output();
Point::init();
}
编译后会发现出现错误:
D:\Program Files\VC6.0\MSDev98\MyProjects\静态\text.cpp(22) : error C2352: 'Point::output' : illegal call of non-static member function
D:\Program Files\VC6.0\MSDev98\MyProjects\静态\text.cpp(6) : see declaration of 'output'
执行 cl.exe 时出错.
text.obj - 1 error(s), 0 warning(s)
注解掉Point::output()函数:
#include <iostream.h>
class Point
{
public:
void output()
{
cout<<"Hello word!"<<endl;
}
static void init()
{
cout<<"Hello!"<<endl;
}
};
void main()
{
/*Point pt;
pt.output();
pt.init();*/
//Point::output();
Point::init();
}
编译可以成功。
通过上例,显然,我们不能通过::来直接调用函数的非静态成员函数。而静态成员函数确实可以直接调用。理由如下:
静态成员函数和静态成员变量属于类本身,在类加载的时候,即为它们分配了空间,所以可以通过类名::函数名或是类名:变量名来访问。而非静态成员函数和非静态成员属于对象的方法和数据,也就是应该首先产生类的对象,然后通过类的对象去引用。
我们在对上例进行修改:
#include <iostream.h>
class Point
{
public:
void output()
{
cout<<"Hello word!"<<endl;
}
static void init()
{
x=0;
y=0;
cout<<"Hello!"<<endl;
}
private:
int x,y;
};
void main()
{
/*Point pt;
pt.output();
pt.init();*/
//Point::output();
Point::init();
}
D:\Program Files\VC6.0\MSDev98\MyProjects\静态\text.cpp(12) : error C2597: illegal reference to data member 'Point::x' in a static member function
D:\Program Files\VC6.0\MSDev98\MyProjects\静态\text.cpp(13) : error C2597: illegal reference to data member 'Point::y' in a static member function
执行 cl.exe 时出错.
text.obj - 1 error(s), 0 warning(s)
边缘出错了:在静态成员中非法引用Point对象的x和y数据成员。
这主要是由于init是一个静态成员函数,不属于某个具体的对象,也就是说在还没产生Point类的任一个具体对象时,该函数就已经存在于程序的代码区了。但是这时,Point类的数据成员x和y还没有分配内存空间,这样,在init函数中对它们进行赋值操作怎么会成功呢?也就是说,在静态成员函数中是不能调用非静态成员的,包括非静态成员函数和非静态成员变量。 即静态成员函数只能访问静态成员变量。
然后,修改上述代码:
#include <iostream.h>
class Point
{
public:
void output()
{
cout<<"Hello word!"<<endl;
}
static void init()
{
x=0;
y=0;
cout<<"Hello!"<<endl;
}
private:
static int x,y;
};
void main()
{
/*Point pt;
pt.output();
pt.init();*/
//Point::output();
Point::init();
}
-------------------Configuration: 静态 - Win32 Debug--------------------
Linking...
text.obj : error LNK2001: unresolved external symbol "private: static int Point::y" (?y@Point@@0HA)
text.obj : error LNK2001: unresolved external symbol "private: static int Point::x" (?x@Point@@0HA)
Debug/静态.exe : fatal error LNK1120: 2 unresolved externals
执行 link.exe 时出错.
静态.exe - 1 error(s), 0 warning(s)
发现,编译没有问题了,但是链接时候却出现错误。这主要是因为静态成员变量,必须对它要进行初始化,并且应该在类的定义之外进行此操作。
我们在类外加上两条初始化语句:
#include <iostream.h>
class Point
{
public:
void output()
{
cout<<"Hello word!"<<endl;
}
static void init()
{
x=0;
y=0;
cout<<"Hello!"<<endl;
}
private:
static int x,y;
};
int Point::x=0;
int Point::y=0;
void main()
{
/*Point pt;
pt.output();
pt.init();*/
//Point::output();
Point::init();
}
编译运行成功。
再看非静态成员函数output。
只注解掉init其他不动。
#include <iostream.h>
class Point
{
public:
void output()
{
x=0;
y=0;
cout<<"Hello word!"<<endl;
}
/*static void init()
{
x=0;
y=0;
cout<<"Hello!"<<endl;
}*/
private:
static int x,y;
};
int Point::x=0;
int Point::y=0;
void main()
{
/*Point pt;
pt.output();
pt.init();*/
Point pt;
pt.output();
//Point::output();
//Point::init();
}
发现编译成功。说明output可以调用静态成员变量,但是也是必须进行初始化的
注解掉init函数。去掉x,y定义中的静态标识static和类外的初始化。
#include <iostream.h>
class Point
{
public:
void output()
{
x=0;
y=0;
cout<<"Hello word!"<<endl;
}
/*static void init()
{
x=0;
y=0;
cout<<"Hello!"<<endl;
}*/
private:
int x,y;
};
//int Point::x=0;
//int Point::y=0;
void main()
{
/*Point pt;
pt.output();
pt.init();*/
Point pt;
pt.output();
//Point::output();
//Point::init();
}
编译成功。
从上,我们可以看到,类的非静态成员函数,必须通过定义类的对象来访问。非静态成员函数可以访问非静态成员变量,也可以访问经过初始化的静态成员变量
而静态成员函数,可以通过类对象和类的作用域两种方法来访问。但是静态成员函数只能访问静态成员变量,而且静态成员变量必须在类外要进行初始化才可以访问到