C++中复制构造函数
复制构造函数
复制构造函数用于:
根据另一个同类型的对象显示或隐式初始化一个对象
复制一个对象,将它作为实参传给一个函数
从函数返回时复制一个对象
初始化顺序容器中的元素
根据元素初始化式列表初始化数组元素
合成的复制构造函数
即使定义了其他构造函数也会合成复制构造函数,执行逐个成员初始化,将新对象初始化为原对象的副本,合成的复制构造函数直接复制内置类型成员的值,类类型成员使用该类的复制构造函数进行复制, 但如果遇上数组,只会复制数组的第一个元素,从而导致浅复制。这时必须自定义复制构造函数。
实例:
class A
{
public:
//char ch[100];
intnum;
charc;
A(intn,char c):num(n),c(c)
{}
};
int main()
{
Atemp_a(1,'f');
Atemp_b(temp_a);
cout<<temp_b.c<<endl;
getchar();
}
合成的复制构造函数按位复制。
定义自己的复制构造函数
如果有数据成员是指针,或者有成员表示在构造函数中分配其他资源,此时需要自己定义构造函数。
如果一个类需要构造函数,则通常需要复制构造函数和析构函数。
复制构造函数的形参并不限制为const,但必须是一个引用。否则导致无限递归。
构造函数不能为虚函数的理由:
1,从存储空间角度
虚函数对应一个vtable,这大家都知道,可是这个vtable其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数。
2,从使用角度
虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀。所以构造函数没有必要是虚函数。
虚函数的作用在于通过父类的指针或者引用来调用它的时候能够变成调用子类的那个成员函数。而构造函数是在创建对象时自动调用的,不可能通过父类的指针或者引用去调用,因此也就规定构造函数不能是虚函数。
3、构造函数不需要是虚函数,也不允许是虚函数,因为创建一个对象时我们总是要明确指定对象的类型,尽管我们可能通过实验室的基类的指针或引用去访问它
但析构却不一定,我们往往通过基类的指针来销毁对象。这时候如果析构函数不是虚函数,就不能正确识别对象类型从而不能正确调用析构函数。
4、从实现上看,vbtl在构造函数调用后才建立,因而构造函数不可能成为虚函数
从实际含义上看,在调用构造函数时还不能确定对象的真实类型(因为子类会调父类的构造函数);而且构造函数的作用是提供初始化,在对象生命期只执行一次,不是对象的动态行为,也没有太大的必要成为虚函数
5、当一个构造函数被调用时,它做的首要的事情之一是初始化它的V P T R。因此,它只能知道它是“当前”类的,而完全忽视这个对象后面是否还有继承者。 当编译器为这个构造函数产生代码时,它是为这个类的构造函数产生代码- -既不是为基类,也不是为它的派生类(因为类不知道谁继承它)。
所以它使用的V P T R必须是对于这个类的V TA B L E。而且,只要它是最后的构造函数调用,那么在这个对象的生命期内, V P T R将 保持被初始化为指向这个V TA B L E, 但如果接着还有一个更晚派生的构造函数被调用,这个构造函数又将设置V P T R指向它的 V TA B L E,等.直到最后的构造函数结束。V P T R的状态是由被最后调用的构造函数确定的。这就是为什么构造函数调用是从基类到更加派生 类顺序的另一个理由。
但是,当这一系列构造函数调用正发生时,每个构造函数都已经设置V P T R指向它自己的 V TA B L E。如果函数调用使用虚机制,它将只产生通过它自己的V TA B L E的调用,而不是最后的V TA B L E(所有构造函数被 调用后才会有最后的V TA B L E)。
C++中复制构造函数的更多相关文章
- C++中复制构造函数与重载赋值操作符总结
前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义: 2.复制构造函数和重载赋值操作符的调用时机: 3.复制构造函数和重载赋值操作符 ...
- C++中复制构造函数与重载赋值操作符
我们都知道,在C++中建立一个类,这个类中肯定会包括构造函数.析构函数.复制构造函数和重载赋值操作:即使在你没有明确定义的情况下,编译器也会给你生成这样的四个函数.例如以下类: class CTe ...
- C++中复制构造函数和赋值操作符
先看一个例子: 定义了一个类:
- C++中复制构造函数被调用的三种情况
C++中的构造函数 c++中的构造函数分为构造函数,和复制构造函数,相比于构造函数,复制构造函数使用更加方便,快捷.构造函数可以有多个,二复制构造函数只能有一个,因为复制构造函数的参数只能是当前类的一 ...
- C++中的复制构造函数
与C++中的构造函数相同,复制构造函数在对象生成过程中同样进行插入对应的Vtable虚表,但在成员变量赋值时,除具有复制构造函数的成员对象外,编译器合成复制构造函数其余均采用”Bitwise copy ...
- java中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?
当新对象被创建的时候,构造函数会被调用.每一个类都有构造函数.在程序中没有给类提供构造函数的情况下,Java编译器会为这个类创建一个默认的构造函数 Java中构造函数重载和方法重载很相似.可以为一个类 ...
- C++类中的特殊成员函数-------复制构造函数
在C++中存在一个特殊函数,他就是复制构造函数,假如我们有类A,如果有A a;A b=a; 在这种情况下利用A类变量a来给同是A类变量的b来赋值,这个时候类会使用复制构造函数,如果我们不显式声明复 ...
- 解析C#类中的构造函数
<解析C#类中的构造函数> 一. C#中的构造函数概述: C#中类包含数据成员和函数成员.函数成员提供了操作类中数据的某些功能,包括方法.属性.构造器和终结器.运算符和索引器. 构造函数 ...
- 剑指offer:赋值运算符函数和复制构造函数
赋值运算符函数 对于定义一个赋值运算符函数时,需要注意一下几点: (1)函数的返回类型必须是一个引用,因为只有返回引用,才可以连续赋值 (2)传入的参数声明为常量引用,可以提高代码效率,同时赋值运算函 ...
随机推荐
- Linux:永久修改网卡的MAC地址
比如:搭建一个虚拟机环境之后,需要N个一样的系统,可以本地复制虚拟机来实现.但是复制之后,网卡的MAC地址一样,无法使用,这时候需要修改网卡的MAC地址,且希望重启系统之后,仍生效的,步骤如下: 1. ...
- TIJ读书笔记06-终结清理和垃圾回收
TIJ读书笔记06-终结清理和垃圾回收 finalize()方法 垃圾回收器如何工作 java的垃圾回收是由jvm来控制的.所以需要java程序员参与的部分不是很多. 但是在这里需要明白一点,java ...
- 开启telnet的几种方法
开启telnet方法一:需要VTY的密码和进入超级权限的密码(VTY虚拟终端,一种网络设备的连接方式) [R1]int g0/0/0[R1-GigabitEthernet0/0/0]ip add 19 ...
- .net正则表达式
1. "^-?[1-9]\\d*$",//整数 2. "^[1-9]\\d*$", //正整数 3. intege2:"^-[1-9]\\d*$&qu ...
- windbg学习!vad
在ring0 !address不能提供详细的信息了 可以尝试用下!vad !vad扩展显示一个或多个虚拟地址详细的虚拟地址描述符(virtual address descriptor (VAD)). ...
- position:absolute和float会隐式的改变display类型
position:absolute和float会隐式的改变display类型,不论之前是什么类型的元素(display:none除外),只要设置了position:absolute或float,都会让 ...
- 先进先出集合queue
先进先出集合queue Enqueue添加到集合最后 Dequeue移除集合第一个对象并返回
- Spring Framework------>Class RestTemplate----->
org.springframework.web.client.RestTemplate 官方文档 学习心得: class RESTTemplate用于管理与客户端的HTTP连接
- iOS应用之微信支付集成-直接前端集成
所有信息的生成都在前端完成,包括对订单进行sign签名以及MD5签名加密(此方法相对来说有些复杂,没有官方给的方法简单).注:官方给的是v3&v4支付流程,签名和加密都是在服务器端进行,由于没 ...
- ubuntu下安装迅雷
----------------------------------2016-03-28新增适用于ubuntu16.04系列的安装包---------------------------------- ...