复制构造函数

复制构造函数

参考链接:

http://c.biancheng.net/view/151.html

1. 简介

也叫拷贝构造函数,构造函数的一种,只有一个参数,参数类型是本类的引用

如果不写复制构造函数,编译器就会自动生成复制构造函数(默认复制构造函数)。

2. 举例

2.1 默认复制构造

#include <iostream>

class A
{
	public:
        int  x , y;
        A( int x,int y) : x(x),y(y) 
        {

        }
};

int main(int argc, char const *argv[])
{
    A a1(1,2);
    // 调用默认的拷贝构造
    A a2(a1);
    std::cout  <<  "a1.x: "<<a1. x << " a1.y: "<<a1. y <<std:: endl;
    std::cout  <<  "a2.x: "<<a2. x << " a2.y: "<<a2. y <<std:: endl;
    return 0;
}

运行结果:

image-20211117143055033

2.2 重写复制构造

#include <iostream>

class A
{
public:
    int  x , y;
    A( int x,int y) : x(x),y(y){}
    
    A( A& a)
    {
        x = a.x;
        y = a.y;
        std::cout << " copy Constructor  no const" << std::endl;
    }

    A(const A& a)
    {
        // a对象中的x,y值没有拷贝到A对象中
        std::cout << " copy Constructor  have const" << std::endl;
    }
};

int main(int argc, char const *argv[])
{
    A a1(1,2);
    const A a2(3,4);
    // 拷贝构造
    // a1 拷贝到 a3,  a1 无const修饰
    A a3(a1);
    // a2 拷贝到 a4,  a2 有const修饰
    A a4(a2);
    std::cout  <<  "a3.x: "<<a3. x << " a3.y: "<<a3. y <<std:: endl;
    std::cout  <<  "a4.x: "<<a4. x << " a4.y: "<<a4. y <<std:: endl;
    return 0;
}

结果:

image-20211117142705950

3. 复制构造函数被调用的三种情况

3.1 当用一个对象去初始化同类的另一个对象时

以上面的代码举例:

A a1(1,2);
A a2(a1); 
//等同于 
A a2 = a1;
初始化和赋值:
// 初始化 
int x = 0;
// 赋值  将y的值赋给x
int x;
int y;
x = y;

3.2 类A的对象作为函数的参数,当调用函数时

#include <iostream>

class A
{  
public:
    int  x , y;
    A( int x,int y) : x(x),y(y) 
    {
        
    }

    A( A& a)
    {
        x = a.x;
        y = a.y;
        std::cout << " copy Constructor " << std::endl;
    }
};

void Fun(A a){}

int main(int argc, char const *argv[])
{
    A a(1,2);
    Fun(a);   
    return 0;
}
//  输出结果:  copy Constructor

image-20211117153342678

3.3 如果函数的返回值是类 A 的对象,则函数返回时,类 A 的复制构造函数被调用

#include <iostream>

class A
{  
public:
    int  x , y;
    A( int x,int y) : x(x),y(y) 
    {
        
    }

    A(const A& a)
    {
        x = a.x;
        y = a.y;
        std::cout << " copy Constructor " << std::endl;
    }
};

A Fun()
{
    A a(1,2);
    return a;
}

int main(int argc, char const *argv[])
{
    std::cout<< Fun().x<<std:: endl;
    return 0;
}

结果输出为:1 并未打印复制构造函数中的输出语句

image-20211117153441990

将Fun()中的a设为全局:

#include <iostream>

class A
{  
public:
    int  x , y;
    A( int x,int y) : x(x),y(y) 
    {
        
    }

    A(const A& a)
    {
        x = a.x;
        y = a.y;
        std::cout << " copy Constructor " << std::endl;
    }
    A operator=(A& a)
    {
        x = a.x;
        y = a.y;
         std::cout << " copy Constructor " << std::endl;
         return *this;
    }
};

A a(1,2);

A Fun()
{
    return a;
}

int main(int argc, char const *argv[])
{
    std::cout<< Fun().x<<std:: endl;
    return 0;
}

结果输出为:

image-20211117153531240

有些编译器出于程序执行效率的考虑,编译的时候进行了优化,函数返回值对象就不用复制构造函数初始化了,这并不符合 C++ 的标准。对这一点,读者不必深究。

4. 自定义String类

#include <iostream>
#include <string.h>

// 自定义字符串类
class String
{
private:
    // 字符
    char * m_Buffer;
    // 字符长度
    unsigned int m_Size;
public:
    
    // 构造函数
    String(const char * string)
    {
        m_Size = strlen(string);
        m_Buffer = new char[m_Size+1];
        memcpy(m_Buffer,string,m_Size);
        m_Buffer[m_Size] = 0;
    }

    // 拷贝构造函数   
    String(const String& str)
        : m_Size(str.m_Size)
    {
        std :: cout << " copy String "<< std ::endl;

        m_Buffer = new char[m_Size + 1];
        memcpy(m_Buffer, str.m_Buffer, m_Size+1);
    }

    //  析构函数  在对象销毁时自动调用
    ~String()
    {
        delete[] m_Buffer;
    }

    //  操作符重载
    char& operator[](unsigned int index)
    {
         std :: cout << "--- []  ---" << std ::endl;
        return m_Buffer[index];
    }

    friend std::ostream& operator << (std::ostream& stream, const String& string);

};

//  重载左移操作符 
//  输出自定义字符串
std::ostream& operator << (std::ostream& stream, const String& string)
{
    std :: cout << "--- <<  ---" << std ::endl;
    stream << string.m_Buffer;
    return stream;
}

int main(int argc, char const *argv[])
{
    String one  = "The Chinese don't lie to the Chinese";
    std :: cout << "---1---" << std ::endl;

    String two  = one;
    std :: cout << "---2---" << std ::endl;

    two[2] = 'a';
    std :: cout << "---3---" << std ::endl;

    std :: cout << one << std ::endl;   
    std :: cout << "---4---" << std ::endl;

  	std :: cout << two << std ::endl;
    std :: cout << "---5---" << std ::endl;

    return 0;
}

输出结果

image-20211123101401673

5. 复制构造函数学习参考链接:

https://www.bilibili.com/video/BV13T4y1P7tw?spm_id_from=333.999.0.0

6. 运算符及重载学习参考链接:

https://www.bilibili.com/video/BV17X4y1M7Vb?spm_id_from=333.999.0.0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值