拷贝(复制)构造函数:
特殊的构造函数
功能:使用一个已经存在的对象来初始化一个新的本类的对象
声明:只有一个参数并且参数为该类对象的引用
class 类名{
public:
类名(类名 &对象名);
};
如果类中没有说明复制构造函数,则系统自动生成一个缺省复制构造函数,作为该类的公有成员
重点:浅复制和深复制
浅)复制:将对象数据成员的值进行简单的复制(最好利用系统自动生成的复制构造函数,已完成浅复制
深复制:不仅将对象数据成员的值进行复制,而且对指针型数据成员生成新空间,然后复制对应的值
对象数组:
CLable *labArr[5] = {
new CLable(30,5,"登录界面"),
new CLable(20,7,"用户名"),
new CLable(20,9,"密码")
};
CLable *labArr[5]
拷贝构造函数的调用情况
CStaff CStaff::getMe()
{
return *this; //返回this指针地址中的值 -- 对象
//返回值 -- 系统需要开辟临时空间存储返回值me =* this 调用接贝构造函数
}
//总结:触发拷贝构造的3种情况 用已经存在的对象初始化一个本类对象 -- 调用拷贝构造函数
1.类对象直接赋值CLabel name= title;
2.类对象作为函数参数时
3.函数返回是类对象
对象作为函数参数、返回值时会调用拷贝构造函数,非常消耗内存空间
推荐使用对象的引用作为函数的参数、返回值--不需要额外开辟空间,避免系统消耗内存空间
&作为返回值时,不会调用拷贝构造函数:
CStaff& CStaff::getMe()
拷贝构造函数的其他作用
当函数的形参是类的对象,调用函数时,进行形参与实参结合时使用。这时要在内存新建立一个局部对象,并把实参拷贝到新的对象中。理所当然也调用拷贝构造函数。
当函数的返回值是类对象,函数执行完成返回调用者时使用。理由也是要建立一个临时对象中,再返回调用者。为什么不直接用要返回的局部对象呢?因为局部对象在离开建立它的函数时就消亡了,不可能在返回调用函数后继续生存,所以在处理这种情况时,编译系统会在调用函数的表达式中创建一个无名临时对象,该临时对象的生存周期只在函数调用处的表达式中。所谓return 对象,实际上是调用拷贝构造函数把该对象的值拷入临时对象。如果返回的是变量,处理过程类似,只是不调用构造函数。
转换构造函数
提供了单个参数的构造函数
相当于将一个其他类型的数值或变量转换为自身类型的数据。
类的构造函数只有一个参数是非常危险的,因为编译器可以使用这种构造函数把参数的类型隐式转换为类类型
class CCube{
public:
CCube(double len){
m_len=len;
}
private:
double m_len;
};
int main(){
CCube cube=12.4;
cube=11;//隐式转换
return 0;
}
explicit关键字:用于参数只有一个的普通构造函数之前
只提供给类的构造函数使用的关键字。
编译器不会把声明为explicit的构造函数用于隐式转换,它只能在程序代码中显示创建对象
类和对象在内存中的关系
1、一个类的多个对象各自拥有类的数据成员的一个副本
2、类的成员函数则被其所有对象共享
3、一个类的不同对象响应相同的消息时,调用的是同一个函数
this指针:
每个对象都有一个指向自身的this指针
(对象的内存地址)
1、对象调用成员函数时会将自己的this指针传递给成员函数(隐含参数) PrintStudent(this);
2、成员函数访问对象的所有数据成员都是通过this指针访问--this一定要加
3、this指针的另外一个作用——访问对象自身(*this)
作用:
1、不同对象调用相同函数时,产生不同的响应
2、用于区分与参数同名的数据成员
类的静态成员:
1、类的数据成员和成员函数都可以声明为static。
2、静态成员解决数据共享的问题
实现共享:在类外设置全局变量,但是,全局变量都有局限性,破坏类的完整性 。类的静态数据成员可以在类的范围内存储数据,这种数据独立于类类型中的任何对象,但可以由这些对象访问。
3.静态成员函数有一种独立于对象的计算能力。
4..类的非静态成员函数可以访问类的静态成员
类中的普通成员对每个对象都有一个单独的副本实例
类中的静态数据成员是该类所有对象所共同拥有的,只有一个实例,它不因对象的建立而产生,也不因对象的失效而删除,它是类定义的一部分,它属于整个类,即属于所有对象
定义: static 数据类型 数据成员名称;
初始化:静态数据成员不能由构造函数初始化,只能在类定义外使用::范围解析来完成
[static] 数据类型 类名::数据成员名称=初始值;
访问:
类名::静态数据成员
静态成员函数:
静态成员函数是操作静态数据成员的函数
定义: static 返回类型 函数名(参数列表)
访问:
类名::静态成员函数
静态成员函数不能声明为const.因为静态成员函数与类的对象无关,它没有this指针,所以不能用const关键字
1、静态成员函数不能访问类的非静态成员变量
2、静态成员函数不能调用非静态成员函数
3、静态成员函数的优点在于:即使不存在类的对象,它们也存在,并且可以调用
4、非静态成员函数可以访问静态数据成员,也可以调用静态成员函数
指针与对象
动态分配对象内存
利用new运算符声明对象并以动态分配内存的方式建立
类名* 指针名=new 类名(参数表);
取成员
对象指针名-> 成员名
Delete 指针名;
对象参数的传递:
对象参数的传递方式一般为传引用方式
const 对象:
如果把一个对象指定为const,就是告诉编译器不要修改它
const对象的定义:
const 类名 对象名(参数表);
const对象不能调用非const成员函数
存取权限的补充 mutable:
用于定义更改频繁的数据成员. 数据成员即使在const对象或在const成员函数中都可以被修改