分类: C/C++
2008-04-23 11:14:53
实 例(1):
void student::input(int number1,float score1)
{
number=number1;
score=score1;
}
void student::input(int number1,float score1)
{
this->number=number1;
this->score=score1;
}
实 例(2):
与malloc函数相比,new运算符会自动调用类的构造函数。new允许在保证完成正确的内存申请的同时将初始数据装入所分配的 空间。
#include
chass point{ //……
public:
point( ){cout<< "Constructor"<
};
void main( )
{
int *pi;
point *pp;
pp=new point;
pi=new int(5);
cout<<*pi<
delete pp;
}
运行结果
Constructor
5
Destructor
在常情况下,一个的各个实例都有它们自己的、属于该类的数据成员和私有拷贝.然而, 若用关键字static声明数据成员,则该数据项的简单拷贝,无论该类创建了多少实例,它始终是存在的(即使类的实例一个也没有创建).例如,以下类定义就定义了静态数据项count:
class CTest
{
public:
static int count;
//...
};
无论CTest类创建了多少实例,count将严格只存放一个拷贝.
除此而外,如果在类中声明了,必须象全局数据项一样,在类外定义和初始化它.由于静态数据成员的定义在类外出现,则必须用作用域分辨符在声明中说明它是哪个类的(本例是CTest::),定义和初始化count可如下例示:
int CTest::count=0;
由于静态数据成员独立于任何类对象存在,在定义时,用类名和作用域分辨符就可以访问它,无需引用类实例.可以把静态数据成员设想为全局变量和该类的正常数据成员的综合.与全局变量一样,它在函数之外定义和初始化,它表示的单个存储单元和整个程序作业一样持久.与正常的数据成员一样,它在类中声明且作用域仅限于这个类,其访问也是受控的(即,它可以是公有、私有、受保护的成员).
成员函数也可以用static关键字修饰,如下例所示:
class CTest
{
//...
static int getCount()
{
//...
}
};
静态成员函数有以下性质:
1.类外的代码可利用类名和作用域分辨符调用这个函数,无需引用一个类的实例(甚至类实例可以不存在),如下例示:
void main()
{
int count=CTest::getCount();
//...
}
2.只可以引用属于该类的静态数据成员或静态成员函数(因为它无需引用一个类实例就可以被调用,静态成员函数没有this指针存放对象的地址.因此,如果它试图访问一个非静态数据成员,编译器无法判定它所访问的数据成员是哪个的).
静态数据成员和静态成员函数可用于保持用于类的数据项或一个类的所有实例共享的数据项.以下程序说明了以静态成员保持一个类的实例当前个数的计量:
#include
class CTest
{
private:
static int count;
public:
CTest()
{
++count;
}
~CTest()
{
--count;
}
static int getCount()
{
return count;
}
};
int CTest::count=0;
void main()
{
cout<
CTest *ptest2=new CTest;
cout<
cout<
本程序打印如下:
1 object exist
实 例(3):
#include
class CTest
{
private:
static int count;
public:
CTest()
{
++count;
}
~CTest()
{
--count;
}
static int getCount()
{
return count;
}
};
int CTest::count=0;
void main()
{
cout<
CTest *ptest2=new CTest;
cout<
cout<
本程序输出如下:
0 object exist
2 object exist
类可以给予另一函数或类存取其私有成员的权力.这样的存取必须将别的类或非成员函数.友员当作类成员对待,并且对对象私有区的存取没有限制.如果要用友员来访问类,友员应在此类中声明.声明的形式是在普通声明之前加上friend关键字.应记住,友员无论是在公有区还是在私有区声明都没关系,它只是将友员的名字引入了类作用域.例如:
class t1
{
private:
int data;
friend void friend_t1(t1 fri); //友员声明
public:
t1(){data=12;}
//...
};
t1声明了外部函数friend_t1()是类t1的友员,friend_t1()的定义如下:
void friend_t1(t1 fri)
{
fri.data=10; //改变了t1的私有变量t1::data的值
}
由于它是类t1的友员,因此可修改类t1中的私有数据.
应注意,友员并不是成员,因此在成员函数中,不能用this指针来访问它.现在假定在t1中加入一成员函数:
void t1::use_friend()
{
t1 fri;
this->friend_t1(fri); //出错,friend_t1不是类成员
::friend_t1(fri); //正确,访问外部函数friend_t1
}
类似的,在外部函数中,也不能通过t1的对象来访问友员friend_t1():
void main()
{
ti fri,fri1;
fri.friend_t1(fri); //出错,friend_t1不是t1的成员函数
friend_t1(fri1); //正确,调用外部函数friend_t1
}
一个类的成员也可以声明为另一个类的友员,例如:
class x{
public:
void f();
//...
private:
int i;
//...
};
class y{
friend void x::f();
int i;
public:
//...
};
y声明x的成员函数f()是它的友员,故x::f()可访问y中的私有变量:
void x::f()
{
y yi;
yi.i=10; //修改了类y的对象yi的私有成员
}
与外部友员函数类似,类成员友员只是它所在类的成员函数,而不是声明它为友员的那个类的成员函数.例如:
y y1;
y1.x::f(); //x::f()不是y的成员函数,出错
x x1;
x1.f(); //正确,x::f()是x的成员函数
甚至可以将整个类声明为另一个类的友员:
class y
{
//...
};
class x
{
friend class y;
//...
};
由于有了这个友员声明,类y的任何成员函数都可以访问类x的私有成员.
友员破坏了,原本只能通过公有接口间接访问的私有数据,现在可以由友员直接访问.因此,友员要了解它所访问的类的实现细节,当此类的实现有所改动,即使公共接口不改变,友员也要跟着改动。声明有友员的类是难修改的,例如:
class sf; //由于在定义sf之前,stack要用到它,先声明sf
class stack
{
char *p; //栈指针
char *v; //栈数组
int sz;
public:
stack(int size);
char pop();
void push(char);
~stack();
friend void sf::f(); //sf::f是stack的友员
};
class sf
{
//...
void f()
{
//使用stack::p和stack::v
}
};
stack声明了sf::f()是它的友员.现在,如果要把stack的数据结构改为链表形式,它不仅要修改pop()和push()的实现,还要修改类sf中f()的实现.也就是说修改从一个模块波及到了另一个模块,而不只限于模块内部.
友员能破坏封装,但也能使程序变得简洁而高效.在具体使用时,应权衡二者,再做适当选择.
实 例(4):
#include
#include
class point{
private:
float x, y;
public:
point(float xi, float yi)
{x=xi; y=yi;}
float Getx( )
{return x;}
float Gety( )
{return y;}
friend float distance(point&a,point&b);
};
float distance(point&a,point&b)
{
float dy=a.y-b.y;
float dx=a.x-b.x;
return sqrt(dx*dx+dy*dy);
}
void main( )
{
point p1(3.0,5.0),p2(4.0,6.0);
float d=distance(p1,p2);
cout<<"The distance is"<
}
运行结果
The distance is 1.414
声明友员函数
友员函数定义时,不使用类名进行定义友员函数不能直接访问类的成员,必须通过对象进行访问。