拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它在创建对象时,使用的是同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:

l  通过使用另一个同类型的对象来初始化新创建的对象;

l  复制对象把它作为参数传递给函数;

l  复制对象,并从函数返回这个对象。

如果类中没有定义拷贝构造函数,编译器会自行定义一个。如果类中带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数最常见的形式如下:

classname(const classname &obj)
{
    //构造函数主体
}

在这里,obj是一个对象的引用,该对象是用于初始化另一个对象的。

/***
copy_constructor.cpp
***/
#include<iostream>
using namespace std;

class Line
{
    public:
        Line(int len);
        Line(const Line & obj);
        ~Line();    
        int getLength(void);
    private:
        int *ptr;
};

Line::Line(int len)
{
    cout << "call construct func" << endl;
    //allocate memory for pointer    
    ptr = new int;
    *ptr = len;
}

Line::Line(const Line &obj)
{
    cout << "call copy constructor func and allocate memory for point" << endl;
    ptr = new int;
    *ptr = *obj.ptr;
}

Line::~Line(void)
{
    cout << "free memory" << endl;
    delete ptr;
}

int Line::getLength(void)
{
    return *ptr;
}

void display(Line obj)
{
    cout << "the size of line : " << obj.getLength() << endl;
}

int main()
{
    Line line(10);
    display(line);
    return 0;
}

运行结果:

exbot@ubuntu:~/wangqinghe/C++/20190806$ ./copy

call construct func

call copy constructor func and allocate memory for point

the size of line : 10

free memory

free memory

void display(Line obj) //通过gdb调试,该程序在 Line obj处进入拷贝函数构造。

如果使用以下的main

int main()
{
    Line line1(10);
    Line line2 = line1;

    display(line1);
    display(line2);
    return 0;
}

运行结果:

exbot@ubuntu:~/wangqinghe/C++/20190806$ ./copy

call construct func

call copy constructor func and allocate memory for point

call copy constructor func and allocate memory for point

the size of line : 10

free memory

call copy constructor func and allocate memory for point

the size of line : 10

free memory

free memory

free memory

在C++中,对象以值传递的方式传入函数参数:

/***
value_transf.cpp
***/
#include<iostream>
using namespace std;

class CExample
{
    public:
        CExample(int b)
        {
            a = b;
            cout << "create: " << a << endl;
        }
        
        //copy constructor
        CExample(const CExample& C)
        {
            a = C.a;
            cout << "copy constructor" << endl;
        }

        //destructor
        ~CExample()
        {
            cout << "delete: " << a << endl;
        }

        void show()
        {
            cout << a << endl;
        }
    private:
        int a;
};

void g_Fun(CExample C)
{
    cout << "test" << endl;
}

int main()
{
    CExample test(1);
    g_Fun(test);
    return 0;
}

运行结果:

exbot@ubuntu:~/wangqinghe/C++/20190806$ g++ value_transf.cpp -o value_transf -g

exbot@ubuntu:~/wangqinghe/C++/20190806$ ./value_transf

create: 1

copy constructor

test

delete: 1

delete: 1

调用g_Fun()时,会产生以下几个重要的步骤:

1) test对象传入形参时,会先产生一个临时变量,暂且称呼C

2) 然后调用拷贝构造函数把test值给C。这两个步骤很像:CExample C

3) 等g_Fun()执行完后,析构掉C对象。

拷贝构造函数是一种特殊的构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用。当定义一个新对象并用一个同类型的对象把它进行初始化时,将显示使用拷贝构造函数或从函数返回该类型的对象时,将隐式调用拷贝构造函数。

C++支持两种初始化形式:

拷贝初始化:int a = 5;和直接初始化 int a(5);

对于其他类型没有什么区别,对于类类型直接初始化直接调用实参匹配的构造函数,拷贝构造初始化总是调用拷贝构造函数,也就是说

A x(2);  //直接初始化,调用构造函数

A y = x; //拷贝初始化,调用拷贝构造函数。

必须定义拷贝构造函数的情况:

只包含类类型成员或内置类型(但不是指针类型)成员的类,无须显示地定义拷贝构造函数也可以拷贝;有的类有一个数据成员是指针,或者是由成员表示在构造函数中分配的其他资源,这两种情况下都必须定义拷贝构造函数。

以下情况使用拷贝构造函数:

类的对象需要拷贝时,拷贝构造函数将会调用。以下情况都会调用拷贝构造函数:

l  一个对象以值传递的方式进入函数体

l  一个对象以值传递的方式从函数返回

l  一个对象需要通过另外一个对象进行初始化

原文地址:https://www.cnblogs.com/wanghao-boke/p/11310843.html