首页 > 编程知识 正文

复制构造函数和拷贝构造函数,复制构造函数原型

时间:2023-05-05 12:08:23 阅读:157763 作者:4544

文章目录默认构造函数和复制构造函数1定义默认构造函数2隐式类类型转换3复制构造函数和合成复制构造函数3.1合成复制构造函数4深度复制和写入复制

默认构造函数和复制构造函数1定义默认构造函数

默认构造函数是在未显式提供初始化表达式时调用的构造函数,它是一个无参数的构造函数。 如果在定义类的对象时未指定初始化表达式,则使用缺省构造函数。

定义默认构造函数的常用格式如下:

类名()函数主体)由没有参数的构造函数定义,或者由所有参数均为默认参数的构造函数定义。 与缺省构造函数对应的对象定义格式如下:

类名对象名称; //对象名称后不需要参数。它位于任何类中,并且只有一个默认构造函数。 如果未在定义的类中显式定义构造函数,编译器将自动为该类生成缺省构造函数。 这称为“合成默认构造函数”(synthesized default constructor )。

即使类只定义了一个构造函数,编译器也不再生成缺省构造函数。 换句话说,如果您为类定义了带参数的构造函数,并且还想要一个不带参数的构造函数,则必须自己定义它。

通常,必须为任何类定义缺省构造函数。 这是因为,在许多情况下,缺省构造函数是由编译器隐式调用的。

2隐式类型转换要实现从其他类型到类型的隐式转换,必须定义相应的构造函数。 要定义从参数类型到该类型的隐式转换,请使用在单个实参(称为转换构造函数)中调用的构造函数。

隐式类型转换示例:

更改对象a的默认参数str

使用单参数构造函数进行类类型转换的方法概括如下:

(1)首先声明类

)2)此类定义一个只有一个参数的构造函数。 参数类型是需要转换的数据类型。 也就是说,转换构造函数的一般形式如下:

类名(const指定数据类型obj ) )3)使用转换构造函数定义对象时,将进行类型转换。 一般形式如下。

类名(具有给定数据类型的数据对象)可以通过将构造函数声明为explicit来防止在需要隐式转换的上下文中使用构造函数,并禁止在构造函数中定义的隐式转换。

c关键字explicit限定用于表示显式的类的构造函数。 explicit关键字只能在类中的构造函数声明中使用,不能在类定义外部重复。

一般来说,单形参数的构造函数必须是explicit,除非有明显的理由想定义隐式转换。 将构造函数设置为explicit可以避免错误,并且可以在需要转换时显式构建对象。

3复制构造函数和合成复制构造函数3.1复制构造函数复制构造函数特殊构造函数,也称为复制构造函数。 其作用是使用已经生成的对象初始化另一个同类对象。

变量初始化:

int a=10; int b=a; 初始化对象:

pointpt1(10,20; Point pt2=pt1; 要实现上述初始化格式,请使用复制构造函数。 其定义的一般形式如下。

类名(const类名obj )函数体)

构造函数具有一个只有这种类型的对象的参考形状参数,通常使用const限定。 由于复制构造函数只是复制对象,因此不需要更改传递的对象的值。

复制构造函数的功能是使用已知对象初始化已创建的类中的对象。

与复制构造函数对应的对象的定义格式如下:

类名对象名1 (按类对象1 )、对象名2 )按类对象2 )、……; 赋值和对象复制之间的差异:

的赋值是对已经存在的对象的赋值,所以在进行赋值之前必须定义要赋值的对象。

复制对象是从无到有地创建新对象,使其与现有对象完全相同,包括对象的结构和成员值。

3.2要合成复制构造函数,每个类都需要一个复制构造函数。 如果类没有定义复制构造函数,编译器将自动合成一个称为“合成复制构造函数”(synthesized copy constructor )的内容。

与合成缺省构造函数不同,即使定义了其他构造函数,编译器也会合成复制构造函数。

若要合成构造函数,请执行每个成员的初始化,并将新对象初始化为原始对象的副本。

“按成员”是指编译器将当前对象中的每个非静态数据成员依次复制到正在创建的对象中。 每个成员的类型决定了要复制的成员的含义。

嵌入式成员直接复制其值; 类类型成员使用该类的复制构造函数进行复制。 如果类包含数组成员,合成复制构造函数将复制数组。 这意味着将数组中的每个元素复制到新对象。 每个成员的初始化可以将合成复制构造函数视为每个数据成员在构造函数初始化列表中初始化的构造函数。

在以下三种情况下使用复制构造函数:

)1)用一个对象显式或隐式初始化另一个对象。

C支持两种初始化格式:复制初始化和直接初始化。 初始化复制时使用等号=,直接初始化时在括号内放置初始化表达式。

初始化副本

和直接初始化是有区别的:直接初始化会调用与实参匹配的构造函数;而复制初始化总是调用复制构造函数。

Point pt1(10,20); Point pt2=pt1; //复制初始化 Point pt3(pt1); //直接初始化

(2)函数参数按值传递对象时或函数返回对象时。

当函数形参为对象类型,而非指针和引用类型时,函数调用按值传递对象,即编译器调用复制构造函数产生一个实参对象副本传递到函数中。

类似地,以对象类型作为返回值时,编译器调用复制构造函数产生一个return语句中的值的副本返回到调用函数。
(3)根据元素初始化式列表初始化数组元素时。
如果没有为类类型数组提供元素初始化式,则将用默认构造函数初 始化每个元素。然而,如果使用常规的大括号的数组初值列表形式 来初始化数组时,则使用复制初始化来初始化每个元素。

总的来说,正是有了复制构造函数,函数才可以传递对象和返回对象,对象数组才能用初值列表的形式初始化

4 深复制与浅复制

如果一个拥有资源(如用new得到的动态内存)的类对象发生复制的时候,若对象数据与资源内容一起复制,称为深复制,如图所示:指针p指向动态内存区

若复制对象但未复制资源内容称为浅复制,如图所示。



C++程序设计-西北工业大学-zjdmf、儒雅的御姐、满意的啤酒

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。