类和对象第五讲
对象的动态建立和释放.例如:
box *pt; //定义一个指向box类对象的指针变量pt
pt=new (box); //在pt中存放了新建对象的起始地址
另外C++还允许在执行new时,对建立的对象进行初始化;
例如: box *pt=new(12,15,18).
在执行new运算时,如果内存量不足,无法开辟所需的内存空间,目前大多数C++编译系统都是用new返回一个0指针.只要检测返回值是否为0,就可判断分配内存是否成功.
Delete pt //释放pt指向空间的内存空间
对象的赋值和复制
首先说下对象的赋值:
#include <iostream>
using namespace std;
class myclass
{
public :
myclass(int =10,int =10,int =10);
int show_my();
private:
int heigh;
int width;
int lenth;
};
myclass :: myclass(int h,int w,int l)
{
heigh=h;
width=w;
lenth=l;
}
int myclass::show_my()
{
return (heigh*width*lenth);
}
int main()
{
myclass m1(15,30,25),m2;
cout<<"m1 = "<<m1.show_my()<<endl;
m2=m1;
cout<<"m2 = "<<m2.show_my()<<endl;
return 0;
}
说明:
(1)对象的赋值支队其中的数据成员赋值,而不对成员函数赋值.这是因为不同对象的成员函数是同一个函数代码段,不需要,也无法对他们赋值.
(2)类的数据成员终不能包括动态分配的数据,否则在赋值时可能出现严重的后果
对象的复制: box box2(box1); 作用就是用已有的对象box1去克隆一个新对象box2;
一般形式为:
类名 对象2(对象1) //用对象1复制出对象2;
再建立一个新对象时调用一个特殊的构造函数——赋值构造函数,这个函数的形式如下:
Box :: box(const box &b)
{
Heigh=b.heigh;
Width=b.width;
Lenth=b.lenth;
}
复制构造函数也是构造函数,但他只有一个参数,这个参数是类本身的对象,而且采用对象的引用形式(一般约定加const声明,使参数值不能改变,以免在调用此函数是因不慎对视对象值被修改)。
对象的赋值则是对一个已存在的对象赋值,因此必须先顶一下被赋值的对象,才能进行赋值。而对象的复制则是从无到有的建立一个新对象,并使它与一个已有的对象完全相同。
例如:
int main()
{
myclass m1(15,30,25);
cout<<"m1 = "<<m1.show_my()<<endl;
myclass m2=m1,m3=m2;
cout<<"m2 = "<<m2.show_my()<<endl;
cout<<"m3 = "<<m3.show_my()<<endl;
return 0;
}
程序在执行完第四行后,三个对象的状态完全相同。
普通构造函数和复制构造函数的区别。
(1)在形式上:
类名(形参列表); //普通构造函数的声明,
类名(类名 &对象名);//复制构造函数的声明。
(2)在建立对象时,实参类型不同。系统会根据实参的类型决定调用那个构造函数。
例如:
box b1(12,15,13); //实参为整数,调用普通构造函数。
box b2(box b1); //实参是对象名,调用复制构造函数。
(3)普通构造函数在程序中建立对象时被调用。
复制构造函数在用已有对象复制一个新对象时被调用。
静态数据成员
静态数据成员是一种特殊的数据成员。它以关键字static开头。例如:
class box
{
public:
int show_v();
private:
static int heigh; //把heigh定义为静态
int weith;
int lenth;
};
如果希望个对象中的height的值是一样的,就可以吧它定义为静态数据成员,这样他就为个对象所共有,而不只属于某个对象的成员,所有对象都可以引用他。静态的数据成员在内存中值占一份空间(而不是每个对象)。每个对象都可以引用这个静态对象的数据成员。静态数据成员的值对所有对象都是一样的。如果改变他的值,则在各对象中的这个数据成员的值都同时改变了。这样可以节省空间,提高效率。
引用静态数据成员:
#include <iostream>
using namespace std;
class box
{
public:
box(int ,int);
int show_v();
static int heigh; //把height定义为共有的静态数据成员
int width;
int lenth;
};
box :: box(int w ,int l) //通过构造函数对width和lenth初始化
{
width=w;
lenth=l;
}
int box::show_v()
{
return (heigh*width*lenth);
}
int box::heigh=10; //静态数据成员height初始化
int main()
{
box a(15,20),b(20,30);
cout<<a.heigh<<endl; //通过对向明a引用静态数据成员
cout<<b.heigh<<endl; //通过对象名b引用静态数据成员
cout<<box::heigh<<endl; //通过类名引用静态数据成员
cout<<a.show_v()<<endl; //调用成员函数,输出结果。
return 0;
}
静态成员函数:(静态成员函数没有this指针)
#include <iostream>
using namespace std;
class myclass
{
public:
myclass (int n,int a,float s)
{
num=n;
age=a;
chengji=s;
}
void total();
static float average();
private:
int age;
int num;
float chengji;
static float sum;
static int count;
};
void myclass::total()
{
sum+=chengji;
count++;
}
float myclass :: average()
{
return (sum/count);
}
float myclass :: sum=0;
int myclass ::count=0;
int main()
{
myclass m1[3]={
myclass(1001,18,70),
myclass(1002,19,78),
myclass(1005,20,98)
};
int n;
cin>>n;
for(int i=0;i<n;i++)
{
m1[i].total();
}
cout<<"the avreage chengji of "<<n<<" student is "<<myclass::average()<<endl;
return 0;
}
静态成员函数如果要在类外调用,形式应该是类名和域运算符“::”,如myclass::average();实际上也可以通过对向明调用成员函数:a.avreage();