类的静态成员函数和非静态成员函数的调用问题

首先,建立一个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();

}


编译成功。

从上,我们可以看到,类的非静态成员函数,必须通过定义类的对象来访问。非静态成员函数可以访问非静态成员变量,也可以访问经过初始化的静态成员变量

而静态成员函数,可以通过类对象和类的作用域两种方法来访问。但是静态成员函数只能访问静态成员变量,而且静态成员变量必须在类外要进行初始化才可以访问到

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值