拷贝构造函数

1.  拷贝构造函数

功能:使用一个已经存在的对象来初始化一个新的同一一类型的对象

声明:只有一个参数并且参数为该类对象的引用

如果类中没有说明拷贝构造函数,则系统自动生成一个缺省复制构造函数,作为该类的公有成员

2.  拷贝构造函数的调用情况

1)  用已有对象初始化对象会调用拷贝构造函数

2)  当函数的形参是类的对象,调用函数时,进行形参与实参结合时使用

3)  当函数的返回值是类对象,函数执行完成返回调用名时使用(返回值不是局部的类对象,当传递对象或返回对象时,一般用引用,由于引用不会调用构造函数,提高效率)

3.  深拷贝与浅拷贝

1)  浅拷贝——使用系统提供的默认构造函数完成的复制,源对象与复制对象共用一份指针,仅仅是引用的变量不同(对象名不同),对其中任何一个对象的改动都会影响另一个对象。

2)  深拷贝——不使用系统提供的默认构造函数,源头对象与复制对象相互独立,其中任何对象的改动都不会对另外一个对象造成影响

3)  赋值操作

void operator=(constString& t);//=运算符必须要实现深拷贝

4)  禁止拷贝

对于独一无二的对象禁止拷贝,将拷贝构造函数私有化

5)  拷贝构造函数与复制运算符重载函数的区别

两者都是从另一个对象中复制函数,但是两者在使用时有很大区别:

A.  是否产生新的对象

拷贝构造函数调用时必须产生一个对象,用一个已存在的对象去构造一个不存在的对象;

=赋值运算符是通过参数传进来,对已经存在的对象赋值,不产生新的对象,用一个已存在的对象去覆盖另一个已存在的对象。

B.  调用的时机不同

拷贝构造函数是用已经存在的对象初始化另一个新的对象,即在对象创建并初始化时调用的;

而=赋值运算符重载函数要在对象初始化完成后才会被调用。

C.  是否释放原来的内存空间(类的数据成员是指针)

拷贝构造函数需要重新申请内存空间,不能和传递的对象共用相同的内存空间,否则在析构函数会出现二次释放的问题;

=赋值运算符函数使用时,对象已经存在,即数据指针的内存空间已经存在,但这段内存空间的长度不一定满足赋值的需求,所以需要先释放已有的内存空间,再根据赋值对象的数据成员大小重新申请内存空间,然后再赋值

示例

[main.cpp]
#include <iostream>
#include "String.h"
 
using namespace std;
 
int main()
{
    String s;//默认构造函数
    s ="hello1";//转换构造函数+赋值构造函数+析构函数
    s.Display();
 
    Strings1("hello2");//转换构造函数
    s1.Display();
 
    Strings2(s1);//拷贝构造函数
    s2.Display();
 
    Strings3("world!");//转换构造函数
    s3 ="hello world";//转换构造函数+赋值构造函数+析构函数
    s3.Display();
   
    return 0;
}
[String.h]
#ifndef _STRING_H_
#define _STRING_H_
 
class String
{
    public:
        String();
    ~String();
    void Display();
    String(char*str);
    String(constString& other);//拷贝构造函数
    String&operator = (const String& other);//=赋值运算服
 
 
    private:
        char *str_;
};
 
#endif
[String.cpp]
#include <iostream>
#include <string.h>
#include "String.h"
 
using namespace std;
 
String::String()
{
    str_ = newchar('\0');
    cout <<"default constructor String" << endl;
}
 
String::~String()
{
    cout <<"destroy String" << endl;
    delete [] str_;
}
 
String::String(char *str)
{
    cout <<"constructor String" << endl;
    int len =strlen(str) + 1;
    str_ = newchar[len];
    memset(str_, 0,len);
    strcpy(str_,str);
}
 
void String::Display()
{
    cout <<str_ << endl;
}
 
String::String(const String& other)
{
    //cout <<"copy" << endl;
    int len =strlen(other.str_) + 1;
    str_ = newchar[len];
    memset(str_, 0,len);
    strcpy(str_,other.str_);
   
}
 
String& String::operator = (const String& other)
{
     //cout<< "=" << endl;
    if(this ==&other)
    {
        return*this;
    }
 
    int len =strlen(other.str_) + 1;
    delete [] str_;
    str_ = newchar[len];
    memset(str_, 0,len);
    strcpy(str_,other.str_);
}


4.  空类默认生成的成员

class Empty

{

Empty();//默认构造函数

Empty(const Empty&);//默认拷贝构造函数

~Empty();//默认析构函数

Empty& operator=(const Empty&);//默认赋值运算符

Empty* operator&();//取地址运算符

const Empty* operator&() const;//取地址运算符const

};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值