静态类数据成员、const与类

每个对象的数据成员都是独立的,在内存中各自独立,但是对象的成员函数的创建和放置在内存中只有一个地方。

一、静态类数据成员:

前面说过每个对象包含它自己独立的数据,但是当数据项被声明为static后,不管存在多少对象,整个类只会创建一个这样的数据项

静态类数据成员与普通静态变量

相同点:只在类中可见,但是生存周期与整个程序相同。即使没有了类的对象,他依然存在。

不同点:普通的静态变量被用来在各个函数调用之间保持信息,而静态的类数据成员是供类中的各对象共享数据。

#include<iostream>
using namespace std;
class foo
{
public:
	foo()
	{
		count++;
	}
	int getcount()
	{
		return count;
	}
private:
	static int count; //静态变量的声明,在类的内部
};
int foo::count = 0;   //静态变量的定义,在类的外部定义
int main()
{
	foo a,b,c,d;
	cout<<a.getcount()<<endl
		<<b.getcount()<<endl
		<<c.getcount()<<endl
		<<d.getcount()<<endl;
	return 0;
}

程序中由于有4个对象,所以构造函数被调用了4次,所以结果为:

但当是自动变量(automatic)时,每个对象只会将自己的私有count加1,所以输出为4个1.

注意此处静态变量的 定义: int foo::count=0;

参数类型 类 ::变量名 = 0 ;

注意:静态变量要使用两个语句,变量的声明出现在类的定义中,而变量的实际定义在类的外部,像全局变量一样。

why:①如果静态数据成员在类的内部定义就违背了这样的思想:类的定义只是一个在内存中不开辟任何空间的蓝图;

②将静态变量的定义置于类之外也强调了在程序执行之前这种数据的内存空间只被分配一次。

二、const成员函数

const成员函数保证了它不会修改任何本对象的数据成员。

把关键字const置于声明符和函数体之间,就可以将一般的函数变为const函数。如果有单独的函数声明,那么声明和定义都要加上const。

distance示例:

#include <iostream>
using namespace std;
class Distance
{
public:
	Distance():feet(0),inches(0.0)
	{}
	Distance(int ft,float in):feet(ft),inches(in)
	{}
	void getdist()
	{
		cout<<"Enter the feet :";cin>>feet;
		cout<<"Enter the inches:";cin>>inches;
	}
	void showdist()
	{
		cout<<feet<<"-"<<inches<<endl;
	}
	Distance add_dist(const Distance&) const;
private:
	int feet;
	float inches;
};
Distance Distance::add_dist(const Distance& d2) const
{
	Distance temp;
	//feet=0;  //error:can't modify this
	//d2.feet=0;  //error:can't modify d2
	temp.inches=inches+d2.inches;
	if (temp.inches>=12.0)
	{
		temp.inches-=12.0;
		temp.feet++;
	}
	temp.feet+=feet+d2.feet;
	return temp;
}
int main()
{
	Distance dist1,dist3;
	Distance dist2(11,6.25);
	dist1.getdist();
	dist3=dist1.add_dist(dist2);
	dist1.showdist();cout<<endl;
	dist2.showdist();cout<<endl;
	dist3.showdist();cout<<endl;
	return 0;
}

示例中 feet=0;错误是因为:语句试图修改调用const成员函数的对象dist1的数据,编译器报错。

d2.feet=0;错误是因为:参数通过引用传递给add_dist,但我们又希望不修改dist2中的变量,所以把d2变为常量类型,一旦修改dis2中的任何数据,编译器报错。

注:如果参数通过引用传递给了常规的函数,而又不希望函数会修改他,那么函数的声明中以及定义中应当把参数设置为const类型。当然这对于成员函数也是成立的。

三、const对象

当对象声明为常量类型后就不能修改他了。而且常量对象只能使用常量函数,但是不能使用非常量函数。

看下面例子:

#include <iostream>
using namespace std;
class Distance
{
public:
	Distance(int ft,float in):feet(ft),inches(in)
	{}
	void getdist()
	{
		cout<<"Enter the feet :";cin>>feet;
		cout<<"Enter the inches:";cin>>inches;
	}
	void showdist() const
	{
		cout<<feet<<"-"<<inches<<endl;
	}
private:
	int feet;
	float inches;
};
int main()
{
	const Distance football(300,0);
	//football.getdist();  //错误:getdist不是常量,不能被常量对象使用
	cout<<"football=";
	football.showdist();
	cout<<endl;
	return 0;
}

因外football是常量对象,此时从getdist获得新值是非法的,编译器会报错。

posted @ 2011-08-10 10:45  csqlwy  阅读(1529)  评论(1编辑  收藏  举报