什么是复制构造函数
展开全部
复制构造函数,直接初始化,复制初始化,赋值,临时对象
复制构造函数应弄清的几个问题:何时调用复制构造函数,复制构造函数有何功能,为什么要定义自已的复制构造函数。 1.复制构造函数:当用户没有定义自已的复制构造函数时系统将生成一个默认的复制构造函数。当按值传递对象时,就会创建一个形参的临时对象,然后调用复制构造函数把临时对象的值复制给实参。
2.默认复制构造函数的功能:将一个对象的非静态成员的值逐个复制给另一个对象,注意复制的是成员的值,这种复制方式也称为浅复制。因为静态成员属于整个类,而不属于某个对象,所以调用复制构造函数时静态成员不会受到影响。
3.何时生成临时对象:情形1:按值传递对象注意是按值传递对象,按值传递意味着会创建一个原始对象的副本, 情形2:函数返回对象时。 情形3:用一个对象初始化另一个对象时即复制初始化,语句hyong x=y和hyong x=hyong(y)这里y是hyong类型的对象。都将调用复制构造函数,但有可能创建临时对象也有可能不创建临时对象而用复制构造函数直接初始化对象,这取决于编译器。 4.临时对象是由复制构造函数创建的,当临时对象消失时会调用相应的析构函数。也就是说只要创建了临时对象就会多调用一次析构函数。
5.何时使用复制构造函数:按值传递对象,函数返回对象,用一个对象初始化另一个对象即复制初始化时,根据元素初始化列表初始化数组元素。这四种情况都将调用复制构造函数。记住,复制构造函数只能用于初始化,不能用于赋值,赋值时不会调用复制构造函数,而是使用赋值操作符。
6.直接初始化:直接初始化是把初始化式放在圆括号中的,对于类类型来说,直接初始化总是调用与实参匹配的构造函数来初始化的,
7.复制初始化与复制构造函数:复制初始化使用=等于符号来初始化,复制初始化也是创建一个新对象,并且其初值来自于另一个已存在的对象,复制初始化总是调用复制构造函数来初始化的,复制初始化时首先使用指定的构造函数创建一个临时对象,然后用复制构造函数将临时对象的每个非static成员依次的复制到新创建的对象。复制构造函数执行的是逐个成员初始化。注意这里是用一个已存在的对象创建另一个新对象,与用构造函数直接创建一个新对象不一样,使用构造函数初始化时不会使用另一个对象。比如有类hyong,则语句hyong m(1,2)调用构造函数直接初始化,而语句hyong n=m则是用已存在的对象m去初始化一个新对象n,属于复制初始化。
8.理解赋值与复制初始化的区别(重点):赋值是在两个已存在的对象间进行的,也就是用一个已存在的对象去改变另一个已存在对象的值。赋值将调用赋值操作符对对象进行操作,赋值操作符将在操作符重载中讲解。比如有类hyong,有语句hyong x(1);hyong y(1,2)则x=y;这就是赋值,因为对象x和y是已经存在的对象,而语句hyong x=y;则是复制初始化,是用一个已存在的对象y去创建一个新对象x,所以是复制初始化。
9.复制初始化和赋值是在两个对象之间进行的操作,而直接初始化则不是。
10.注意:使用复制构造函数不一定创建临时对象就如语句hyong x=hyong(y),其中y是hyong类型的对象,就有可能不创建临时对象,这取决于编译器。这里如果创建了临时对象则当临时对象消亡时将调用一次析构函数,而如果没有调用而是直接用复制构造函数初始化对象的就不会调用析构函数。
11.复制构造函数的形式:hyong(const hyong & obj);它接受一个指向类对象的常量引用作为参数。定义为const是必须的,因为复制构造函数只是复制对象,所以没必要改变传递来的对象的值,声明为引用可以节省时间,如果是按值传递的话就会生成对象的副本,会浪费资源,而引用就不会。
12.为什么需要定义自已的复制构造函数:如果类只包含类类型成员和内置类型的成员,则可以不用显示定义复制构造函数。但如果类中包含有指针或者有分配其他类型资源时就必须重新定义复制构造函数。因为类中有指针成员,当把用一个对象初始化另一个对象时,这时两个对象中的指针都指向同一段内存,这时如果其中一个对象被消毁了,这时对象中指针所指向的内存也同样被消毁,但另一个对象确不知道这种情况,这时就会出现问题。比如hyong类中含有一个成员指针p,当声明了hyong x=y其中y也是hyong类的对象,这时对象x和y中的指针成员p都指向同一段内存,而如果y被消毁,但x还没被消毁时就会出问题,这时y中对象的成员指针p已经释放了该内存资源,而x中的成员指针p还不知道已经释放了该资源,这时就会出问题。因为对象x和y中的成员指针共享同一段内存,所以对y中的成员指针p的修改就会影响到对象x中的成员指针。所有这些情况都需要重定义复制构造函数来显示的初始化成员的值,这种初始化方式也被称为深度复制。
13.如果显示定义了复制构造函数则调用显示复制构造函数来直接初始化对象,如果没有显示定义复制构造函数,则调用默认的复制构造函数直接初始化对象。
14.注意:1.在VC++中语句hyong n=m不生成临时对象,但如果显示定义了复制构造函数则调用显示复制构造函数来直接初始化对象n,如果没有显示定义复制构造函数,则调用默认的复制构造函数直接初始化对象n。 2.在VC++中语句hyong m1=hyong(m)有可能生成临时对象也有可能不生成临时对象,如果显示定义了复制构造函数则用复制构造函数直接初始化对象m1,不生成临时对象。如果没有显示定义复制构造函数则复制构造函数将创造临时对象,初始化对象m1
15.C++自动提供的成员函数,有:默认构造函数,复制构造函数,默认析构函数,赋值操作符,地址操作符即this指针,这五种函数如果用户没有定义,则系统会自动创建一个。
16.直接调用类中的构造函数:可以在类中的函数,类外的独立函数,即main()函数中直接调用某一个类的构造函数,比如在main函数中可以有语句n=A(4);这里n是类A的对象,这里就是直接调用类A的构造函数创建一个类A的临时对象,然后把该临时对象的值赋给类A的对象n。在类中的函数和在类外的函数调用类的构造函数的方法和这里类似。注意语句n.A(4)是错误的语句,不能由对象调用类中的构造函数。
复制构造函数应弄清的几个问题:何时调用复制构造函数,复制构造函数有何功能,为什么要定义自已的复制构造函数。 1.复制构造函数:当用户没有定义自已的复制构造函数时系统将生成一个默认的复制构造函数。当按值传递对象时,就会创建一个形参的临时对象,然后调用复制构造函数把临时对象的值复制给实参。
2.默认复制构造函数的功能:将一个对象的非静态成员的值逐个复制给另一个对象,注意复制的是成员的值,这种复制方式也称为浅复制。因为静态成员属于整个类,而不属于某个对象,所以调用复制构造函数时静态成员不会受到影响。
3.何时生成临时对象:情形1:按值传递对象注意是按值传递对象,按值传递意味着会创建一个原始对象的副本, 情形2:函数返回对象时。 情形3:用一个对象初始化另一个对象时即复制初始化,语句hyong x=y和hyong x=hyong(y)这里y是hyong类型的对象。都将调用复制构造函数,但有可能创建临时对象也有可能不创建临时对象而用复制构造函数直接初始化对象,这取决于编译器。 4.临时对象是由复制构造函数创建的,当临时对象消失时会调用相应的析构函数。也就是说只要创建了临时对象就会多调用一次析构函数。
5.何时使用复制构造函数:按值传递对象,函数返回对象,用一个对象初始化另一个对象即复制初始化时,根据元素初始化列表初始化数组元素。这四种情况都将调用复制构造函数。记住,复制构造函数只能用于初始化,不能用于赋值,赋值时不会调用复制构造函数,而是使用赋值操作符。
6.直接初始化:直接初始化是把初始化式放在圆括号中的,对于类类型来说,直接初始化总是调用与实参匹配的构造函数来初始化的,
7.复制初始化与复制构造函数:复制初始化使用=等于符号来初始化,复制初始化也是创建一个新对象,并且其初值来自于另一个已存在的对象,复制初始化总是调用复制构造函数来初始化的,复制初始化时首先使用指定的构造函数创建一个临时对象,然后用复制构造函数将临时对象的每个非static成员依次的复制到新创建的对象。复制构造函数执行的是逐个成员初始化。注意这里是用一个已存在的对象创建另一个新对象,与用构造函数直接创建一个新对象不一样,使用构造函数初始化时不会使用另一个对象。比如有类hyong,则语句hyong m(1,2)调用构造函数直接初始化,而语句hyong n=m则是用已存在的对象m去初始化一个新对象n,属于复制初始化。
8.理解赋值与复制初始化的区别(重点):赋值是在两个已存在的对象间进行的,也就是用一个已存在的对象去改变另一个已存在对象的值。赋值将调用赋值操作符对对象进行操作,赋值操作符将在操作符重载中讲解。比如有类hyong,有语句hyong x(1);hyong y(1,2)则x=y;这就是赋值,因为对象x和y是已经存在的对象,而语句hyong x=y;则是复制初始化,是用一个已存在的对象y去创建一个新对象x,所以是复制初始化。
9.复制初始化和赋值是在两个对象之间进行的操作,而直接初始化则不是。
10.注意:使用复制构造函数不一定创建临时对象就如语句hyong x=hyong(y),其中y是hyong类型的对象,就有可能不创建临时对象,这取决于编译器。这里如果创建了临时对象则当临时对象消亡时将调用一次析构函数,而如果没有调用而是直接用复制构造函数初始化对象的就不会调用析构函数。
11.复制构造函数的形式:hyong(const hyong & obj);它接受一个指向类对象的常量引用作为参数。定义为const是必须的,因为复制构造函数只是复制对象,所以没必要改变传递来的对象的值,声明为引用可以节省时间,如果是按值传递的话就会生成对象的副本,会浪费资源,而引用就不会。
12.为什么需要定义自已的复制构造函数:如果类只包含类类型成员和内置类型的成员,则可以不用显示定义复制构造函数。但如果类中包含有指针或者有分配其他类型资源时就必须重新定义复制构造函数。因为类中有指针成员,当把用一个对象初始化另一个对象时,这时两个对象中的指针都指向同一段内存,这时如果其中一个对象被消毁了,这时对象中指针所指向的内存也同样被消毁,但另一个对象确不知道这种情况,这时就会出现问题。比如hyong类中含有一个成员指针p,当声明了hyong x=y其中y也是hyong类的对象,这时对象x和y中的指针成员p都指向同一段内存,而如果y被消毁,但x还没被消毁时就会出问题,这时y中对象的成员指针p已经释放了该内存资源,而x中的成员指针p还不知道已经释放了该资源,这时就会出问题。因为对象x和y中的成员指针共享同一段内存,所以对y中的成员指针p的修改就会影响到对象x中的成员指针。所有这些情况都需要重定义复制构造函数来显示的初始化成员的值,这种初始化方式也被称为深度复制。
13.如果显示定义了复制构造函数则调用显示复制构造函数来直接初始化对象,如果没有显示定义复制构造函数,则调用默认的复制构造函数直接初始化对象。
14.注意:1.在VC++中语句hyong n=m不生成临时对象,但如果显示定义了复制构造函数则调用显示复制构造函数来直接初始化对象n,如果没有显示定义复制构造函数,则调用默认的复制构造函数直接初始化对象n。 2.在VC++中语句hyong m1=hyong(m)有可能生成临时对象也有可能不生成临时对象,如果显示定义了复制构造函数则用复制构造函数直接初始化对象m1,不生成临时对象。如果没有显示定义复制构造函数则复制构造函数将创造临时对象,初始化对象m1
15.C++自动提供的成员函数,有:默认构造函数,复制构造函数,默认析构函数,赋值操作符,地址操作符即this指针,这五种函数如果用户没有定义,则系统会自动创建一个。
16.直接调用类中的构造函数:可以在类中的函数,类外的独立函数,即main()函数中直接调用某一个类的构造函数,比如在main函数中可以有语句n=A(4);这里n是类A的对象,这里就是直接调用类A的构造函数创建一个类A的临时对象,然后把该临时对象的值赋给类A的对象n。在类中的函数和在类外的函数调用类的构造函数的方法和这里类似。注意语句n.A(4)是错误的语句,不能由对象调用类中的构造函数。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |