红皮书(P99-103)
2016.3.22
对象的赋值和复制
一、对象的赋值
对象给对象赋值,赋的是所有的数据成员的值,依旧用“=”(这里的等于号是运算符的重载),这个过程实质上是成员的复制,即将一个数据成员的存储空间的状态赋值给另一个对象的数据成员的存储空间,而成员函数是公用的,不占存储空间,因此谈不上拷贝。
格式:
对象名1=对象名2;
box2=box1;
注意:
1、这两个对象必须属于同一个类
对象的赋值只针对数据成员,不包含成员函数赋值。(见上面的黑体解释)。
2、类的数据成员不能包括动态分配的数据。(否则会出现严重的错误)
二、对象的复制
情景:需要大量的一模一样的对象的时候,复制对象是从无到有。
定义:
类名 对象2 (对象1); //对象2是新的克隆的
Box box2(box1); //用已有的对象box1去克隆box2
OR
类名 对象2=对象1;
Box box2=box1; //用box1初始化box2
本质上:调用复制构造函数
复制构造函数也有默认的,在不需要指定的情况下不需要自己写
Box::Box(const Box & b)
{
higth=b.higth;
width=b.width;
lenth=b.lenth;
}
复制构造函数和普通构造函数的区别:
复制构造函数的形参是类对象,一般声明为const,且这个类必须是本类,不能是其余的类。实参是对象名。在复制的时候调用
普通构造函数的形参是参数表。实参是实参表。在建立对象的时候调用。
复制构造函数适用的场景:
1、程序需要建一个新对象,并用同一个对象对它初始化
2、当函数的参数是类对象时,调用时需要将实参完完整整的传递给形参,即拷贝实参。
例:
void fun (Box b){}
Box box1;
fun(box1); //实参是类的对象,则调用函数时会复制一个新的对象b
Box f() //函数是类类型的
{
Box box2(10,2,45);
return box2; //返回值是类对象
}
Box box1;
box1=f();//将返回值赋给一个新的对象;用的是复制
//因为box2在f()函数结束后就不存在了,而传向main函数的是它的拷贝,这样就好理解了。
return 0;
这些系统可以自动调用,不需要作者费心。
对象的赋值和复制的区别:
赋值是:已有对象对其赋值,必须先声明这个对象,在这个对象存在的情况下进行赋值;(只针对数据成员赋值)
复制是:新建一个对象,使他和原有的对象一模一样。(包括成员和结构)即:
赋值:
Box box1,box2;
box2=box1;
复制:
Box box2=box1;
静态成员
1、静态数据成员
1、静态成员是为了给所有成员共享数据或者函数的(所以任何一个对象都可以引用),以实现全局变量的功能。这样声明为静态的成员的值在每个对象中的值都是一样的。
2、静态数据成员不同于一般的数据成员,一般数据成员在定义对象时才分配存储空间,但是静态数据成员是共享的,所以不属于任何一个对象,只属于类。即为它在程序编译时才分配存储空间,程序结束释放。不随对象的建立撤销而撤销。
3、静态数据成员可以初始化,但是只能在类外初始化。也就意味着必须带上类名:
int Box : : height = 10;
一般形式:
数据类型 类名::静态数据成员名=初值;
注意:
1、初始化操作不加关键字static。
2、不能用参数初始化表对其初始化。
3、公有的静态数据成员的引用可以用类名,也可以用对象名。即:
class Box()
{
public:
Box(int ,int);
static int height;//声明需要及关键字static
int weight;
int lenth;
};
int Box::height=10; //类外定义,不需要加关键字
cout<<box1.height<<endl;
cout<<Box::height<<endl;
//这两句话都是对的,所以不用建立对象,也能引用静态数据成员
二、静态成员函数
1、同理静态成员函数是属于类的,并不属于对象,调用也有两种方式:
1、box1.height
2、Box::height
2、静态成员函数没有this指针。普通的成员函数调用时会有个指向这个函数的指针,但是静态的不属于哪个对象,因此没有指针。所以静态成员函数不能访问本类中的非静态成员函数。
3、作用:静态成员函数主要访问静态数据成员,不访问非静态的数据成员。(这是好习惯)
若要访问非静态的,则必须加限定条件:
box1.width;
即加上对象名和成员运算符