zoukankan      html  css  js  c++  java
  • C++ 复制构造函数

    ——复制构造函数用于将一个对象的值复制到新创建的对象中,用于初始化过程中(包括按值传递参数),而不是常规的赋值过程中

    原型:

    Class_name(const Class_name &)
    

      

    何时调用:

    • 新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用
    StringBad ditto(motto);    // calls StringBad(const StringBad &)
    StringBad metoo = motto;    // calls StringBad(const StringBad &)
    StringBad also = StringBad(motto);    // calls StringBad(const StringBad &)
    StringBad * pStringBad = new StringBad(motto)    // calls StringBad(const StringBad &)
    

      中间两种声明可能会使用复制构造函数直接创建metoo和also,也可能使用复制构造函数生成一个临时对象,然后将临时对象的内容赋给metoo和also,这取决于具体的实现

    • 每当生成了对象副本时,编译器都将使用复制构造函数。具体地说按值传递和返回对象时,都将调用复制构造函数(按值传递意味着创建原始变量的一个副本)。
    • 由于按值传递对象时将调用复制构造函数,因此应该按引用传递对象。这样可以节省调用构造函数的时间以及存储新对象的空间

    功能:

    ——默认的复制构造函数逐个复制非静态成员(成员复制也称为浅复制),复制的是成员的值

    StringBad sailor = sports;
    
    //等效于
    
    StringBad sailor;
    sailor.str = sports.str;
    sailor.len = sports.len;
    

      只是由于私有成员是无法访问的,因此后面的代码不能通过编译

    静态对象不受影响,因为它们属于整个类,而不是各个对象

    默认复制构造函数的问题:

    一:

    默认的复制构造函数不说明其行为(全盘复制),如果需要在构造函数中修改类静态数据成员,这时就会发生错误

    解决办法:提供一个显示复制构造函数

    StringBad::StringBad(const String &s)
    {
        num_strings++;    // static int num_strings声明在类中
        ... // imported stuff to go here
    }
    

      

    如果类中包含这样的静态数据成员,即其值将在新对象被创建时发生变化,则应该提供一个显示复制构造函数

    二:

    隐式复制构造函数的浅复制(复制指针)导致的内存问题

    • 新对象可能修改指针指向的内存
    • 新对象若走完生命周期将会调用析构函数释放指针指向的内存,但当原对象也调用析构函数时,由于该段内存已被释放,这将导致不确定的、可能有害的结果,另一个症状是试图释放内存两次可能导致程序异常终止

    解决办法:定义一个显示复制构造函数,进行深度复制

    StringBad::StringBad(const StringBad &st)
    {
        num_strings++;    // handle static member update
        len = st.len;    // same length
        str = new char [len + 1];    // allot space
        std::strcpy(str, st.str);    // copy string to new location
        ...
    }
    

      复制字符串并将副本的地址赋给str成员

    如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而不是指针,这被称为深度复制。复制的另一种形式(成员复制或浅复制)只是复制指针值。浅复制仅浅浅地复制指针信息,而不会深入“挖掘”以复制指针引用地结构

  • 相关阅读:
    JAVA 正则表达式 (超详细)
    <select>改造成<s:select>实现表单的回显功能
    打开新界面
    list删除操作 java.util.ConcurrentModificationException
    C# 增加 删除 更新 方法
    C# 网页内容获取
    excel 处理方法
    C# 读取excel
    sql 导入excel 遇到问题
    DataSet
  • 原文地址:https://www.cnblogs.com/suui90/p/13126933.html
Copyright © 2011-2022 走看看