对象的动态建立和释放
之前定义的对象是静态的,在程序运行过程中,对象所占的空间不能随时释放,只有在该函数结束时,该对象才释放。可以用new运算符动态建立对象,用delete运算符撤销对象,这样在需要用到对象时才建立对象,不需要用该对象时撤销对象,释放空间,提高内存空间利用率。
对象的赋值和复制
对象的赋值
如果对一个类定义了两个或多个对象,则这些同类的对象之间可以互相赋值,或者说,一个对象的值可以赋给另一个同类的对象,这里所指的对象的值是指对象中所有数据成员的值。
对象之间的赋值也是通过赋值运算符“=”进行的,实际上这个过程是通过成员复制来完成的,即将一个对象的成员值一一复制给另一对象的对应成员。
对象赋值的一般形式为 对象名1=对象名2;
注意,对象名1和对象名2必须属于同一个类。
例1:将一个立方体对象的值赋给另一个立方体对象。
#include <iostream>
using namespace std;
class Box
{
public:
Box(int = 10, int = 10, int = 10);
int volume();
private:
int height, width, length;
};
Box::Box(int h, int w, int len)
{
height = h;
width = w;
length = len;
}
int Box::volume()
{
return (height * width * length);
}
int main()
{
Box box1(12, 13, 14), box2;
cout << "volume1 = " << box1.volume() << endl;
box2 = box1;
cout << "volume2 = " << box2.volume() << endl;
return 0;
}
需要注意的是
对象的赋值只对其中数据成员赋值,而不对成员函数赋值;类的数据成员中不能包括动态分配的数据,否则在赋值时可能出现严重后果。
对象的复制
有时需要用到多个完全相同的对象,就需要使用对象的复制机制,用一个已有的对象快速地复制出多个完全相同的对象。
其一般形式为 类名 对象2(对象1)
在建立对象时调用一个特殊的构造函数--复制构造函数。
复制构造函数也是构造函数,但它只有一个参数,这个参数是本类的对象,而且采用对象的引用形式,此复制构造函数的作用就是将实参对象的各个成员值一一赋给新的对象中对应的成员。
C++还提供另一种方便用户的复制形式,用赋值号代替括号,其一般形式为 类名 对象名1=对象名2;
这种形式看起来很直观,用起来很方便,但是其作用都是调用复制构造函数。
对象的复制和对象的赋值的区别:对象的赋值是对一个已经存在的对象赋值,因此必须先定义被赋值的对象,才能进行赋值;而对象的复制是从无到有地建立一个新对象,并使它与一个已有的对象完全相同,包括对象的结构和成员的值。
不同对象间的数据共享
如果想在同类的多个对象之间实现数据共享,也不要用全局对象,可以用静态的数据成员。
把数据定义为静态
静态数据成员是一种特殊的数据成员,它以关键字static开头。
如果希望同类的各对象中的数据成员的值是一样的,就可以把它定义为静态数据成员,这样它就为各对象所共有,而不属于某个对象的成员,所有对象都可以引用它。静态的数据成员在内存中只占一份空间。
每个对象都可以引用这个静态数据成员,静态数据成员的值对所有对象都是一样的,如果改变它的值,则在各对象中这个数据成员的值都同时改变了。
静态数据成员是在所有对象之外单独开辟空间;不随对象的建立分配空间,也不随对象的撤销而释放。
静态数据成员可以初始化,但只能在类体外进行初始化;静态数据成员既可以通过对象名引用,也可以通过类名引用。
例2:用立方体类Box定义两个对象,引用不同对象中静态数据成员。
#include <iostream>
using namespace std;
class Box
{
public:
Box(int, int);
int volume();
static int height;
int width, length;
};
Box::Box(int w, int len)
{
width = w;
length = len;
}
int Box::volume()
{
return (height * width * length);
}
int Box::height = 10;
int main()
{
Box a(12, 13), b(14, 15);
cout << "a.height = " << a.height << endl;
cout << "b.height = " << b.height << endl;
cout << Box::height << endl;
cout << "a.volume() = " << a.volume() << endl;
return 0;
}
在类外可以通过对象名访问公用的静态数据成员,也可以通过类名引用静态数据成员。即使没有定义类对象,也可以通过类名访问静态数据成员。
如果静态数据成员被定义为私有的,则不能在类外直接引用,而必须通过公用的成员函数引用。
用静态成员函数访问静态数据成员
成员函数也可以定义为静态的,在类中声明函数的前面加static就成了静态成员函数。
静态成员函数是类的一部分而不是对象的一部分,如果要在类外调用公用的静态成员函数,要用类名和域运算符,实际上也允许通过对象名调用静态成员函数,但并不意味此函数属于对象,只是用对象的类型而已。
静态成员函数是为了能处理静态数据成员,静态成员函数与非静态成员函数的根本区别是,非静态成员函数有this指针,而静态成员函数没有this指针,因此静态成员函数不能访问本类中的非静态成员。
如果一定要引用本类的非静态成员,应该加对象名和成员运算符。
例3:统计学生平均成绩,使用静态成员函数。
#include <iostream>
using namespace std;
class Student
{
public:
Student(int n,int a,float s):num(n),age(a),score(s){}
void total();
static float average();
private:
int num, age;
float score;
static float sum;
static int count;
};
void Student::total()
{
sum += score;
count++;
}
float Student::average()
{
return(sum / count);
}
float Student::sum = 0;
int Student::count = 0;
int main()
{
Student stu[3] = {
Student(1001,12,70),
Student(1002,13,80),
Student(1003,14,90)
};
int n;
cout << "num of stu: ";
cin >> n;
for (int i = 0; i < n; i++)
stu[i].total();
cout << "average = " << Student::average() << endl;
return 0;
}

被折叠的 条评论
为什么被折叠?



