复制构造函数

复制构造函数用于:

根据另一个同类型的对象显示或隐式初始化一个对象

复制一个对象,将它作为实参传给一个函数

从函数返回时复制一个对象

初始化顺序容器中的元素

根据元素初始化式列表初始化数组元素

合成的复制构造函数                                               

即使定义了其他构造函数也会合成复制构造函数,执行逐个成员初始化,将新对象初始化为原对象的副本,合成的复制构造函数直接复制内置类型成员的值,类类型成员使用该类的复制构造函数进行复制, 但如果遇上数组,只会复制数组的第一个元素,从而导致浅复制。这时必须自定义复制构造函数。

实例:

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++中复制构造函数的更多相关文章

  1. C++中复制构造函数与重载赋值操作符总结

    前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义: 2.复制构造函数和重载赋值操作符的调用时机: 3.复制构造函数和重载赋值操作符 ...

  2. C++中复制构造函数与重载赋值操作符

    我们都知道,在C++中建立一个类,这个类中肯定会包括构造函数.析构函数.复制构造函数和重载赋值操作:即使在你没有明确定义的情况下,编译器也会给你生成这样的四个函数.例如以下类:   class CTe ...

  3. C++中复制构造函数和赋值操作符

    先看一个例子: 定义了一个类:

  4. C++中复制构造函数被调用的三种情况

    C++中的构造函数 c++中的构造函数分为构造函数,和复制构造函数,相比于构造函数,复制构造函数使用更加方便,快捷.构造函数可以有多个,二复制构造函数只能有一个,因为复制构造函数的参数只能是当前类的一 ...

  5. C++中的复制构造函数

    与C++中的构造函数相同,复制构造函数在对象生成过程中同样进行插入对应的Vtable虚表,但在成员变量赋值时,除具有复制构造函数的成员对象外,编译器合成复制构造函数其余均采用”Bitwise copy ...

  6. java中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?

    当新对象被创建的时候,构造函数会被调用.每一个类都有构造函数.在程序中没有给类提供构造函数的情况下,Java编译器会为这个类创建一个默认的构造函数 Java中构造函数重载和方法重载很相似.可以为一个类 ...

  7. C++类中的特殊成员函数-------复制构造函数

    在C++中存在一个特殊函数,他就是复制构造函数,假如我们有类A,如果有A a;A b=a;   在这种情况下利用A类变量a来给同是A类变量的b来赋值,这个时候类会使用复制构造函数,如果我们不显式声明复 ...

  8. 解析C#类中的构造函数

    <解析C#类中的构造函数> 一.  C#中的构造函数概述: C#中类包含数据成员和函数成员.函数成员提供了操作类中数据的某些功能,包括方法.属性.构造器和终结器.运算符和索引器. 构造函数 ...

  9. 剑指offer:赋值运算符函数和复制构造函数

    赋值运算符函数 对于定义一个赋值运算符函数时,需要注意一下几点: (1)函数的返回类型必须是一个引用,因为只有返回引用,才可以连续赋值 (2)传入的参数声明为常量引用,可以提高代码效率,同时赋值运算函 ...

随机推荐

  1. 点击弹出固定大小的新窗口(js实现)

    <SCRIPT LANGUAGE="javascript"> <!-- window.open ('page.html') --> </SCRIPT& ...

  2. [Tomcat 源码分析系列] (附件) : setclasspath.bat 脚本

    @echo off rem Licensed to the Apache Software Foundation (ASF) under one or more rem contributor lic ...

  3. asp.net项目下的web service返回json数据问题

    App_Code目录下放置WebService.cs文件,文件内容如: using System; using System.Collections.Generic; using System.Dat ...

  4. 8.9 CSS知识点2

    4.关系选择符 包含选择符(Descendant combinator) E F  选择所有被E元素包含的F元素 <style type="text/css"> h1 ...

  5. 【过程改进】10分钟进阶Nuget

    目录 nuget初识 nuget本地包 nuget解决依赖冲突 nuget是什么 .net版的maven(java)? 如果你用过windows的chocolatey,mac的homebrew或许更容 ...

  6. Net分布式系统之二:CentOS系统搭建Nginx负载均衡(下)

    上一篇文章介绍了VMWare12虚拟机.Linux(CentOS7)系统安装.部署Nginx1.6.3代理服务做负载均衡.接下来介绍通过Nginx将请求分发到各web应用处理服务. 一.Web应用开发 ...

  7. Android菜鸟成长记3-activity类

    Activity 一.什么是activity Activity 是用户接口程序,原则上它会提供给用户一个交互式的接口功能.它是 android 应用程序的基本功能单元.Activity 本身是没有界面 ...

  8. .NET/C#/Oracle数据库操作类

    public static class OracleHelper { //数据库连接字符串 private readonly static string connstr = Configuration ...

  9. EXCEL工作表保护密码忘记了,如何撤消工作表保护?

    按下面步骤操作,如果不会发邮件给我吧 SamRichard@live.cn 1\打开文件 2\工具---宏----录制新宏---输入名字如:aa 3\停止录制(这样得到一个空宏) 4\工具---宏-- ...

  10. 奇怪的margin,padding,table

    为什么有的时候margin,padding不管用?写了float以后就管用了? 为什么table 不给width,就默认是100%,里面的td会平均分配teble的宽度,若你想给其中一些td宽度,剩下 ...