C++第六节:拷贝构造函数

拷贝构造函数

拷贝构造函数:通过拷贝一个已有对象来创建一个新的对象

1、声明一个对象,并用另一个已经存在的对象初始化:

     1.1把已经存在的对象作为新声明对象的构造函数的参数

     1.2声明一个对象,并用赋值表达式,用一个已有对象来初始化它

     1.3用new运算符,在堆上创建对象,并用一个已有对象对其进行初始化时

2、传值的方式,从函数返回一个对象:

     2.1向函数传参时,传值调用时,形参是实参的拷贝

     2.2从函数传值返回对象时,创建一个临时对象,接受返回值,会调用拷贝构造函数

三大件:拷贝构造函数、析构函数、赋值运算符的重载

Vector.h

#ifndef __C__No731Class__Vector__
#define __C__No731Class__Vector__

#include <iostream>
using namespace std;
class Vector
{
public:
    int * rep;
    int size;
    
    Vector (int s = 0);
    Vector (int *r, int s);
    Vector (const Vector & v);  //拷贝构造函数
    ~Vector();
    const Vector & operator = (const Vector & v);  //重载赋值运算符
    void print();
};
#endif /* defined(__C__No731Class__Vector__) */
Vector.cpp

#include "Vector.h"
Vector::Vector (int s) : size(s)
{
    if (size <= 0)
        rep = NULL;
    else
    {
        rep = new int[size];
        for (int count = 0; count < size; ++count)
            rep[count] = 0;
    }
    cout << "默认构造函数" << endl;
}
Vector::Vector (int *r, int s)
{
    size = s;
    rep = new int[s];
    for (int count = 0; count < size; ++count)
        rep[count] = r[count];
    cout << "非默认构造函数" << endl;
}
Vector::Vector (const Vector &v)
{
    size = v.size;
    rep = new int[size];
    for (int count = 0; count < size; ++count)
        rep[count] = v.rep[count];
    cout << "重载构造函数" << endl;
}
Vector::~Vector()
{
    if(rep)
    {
        delete [] rep;
        rep = NULL;
    }
    cout << "析构Vector" << endl;
}
const Vector & Vector::operator = (const Vector & v)
{
    if (this != &v)
    {
        delete [] rep;
        rep = new int[v.size];
        for (int i = 0; i < v.size; ++i)
            rep[i] = v.rep[i];
        size = v.size;
    }
    cout << "重载=" << endl;
    return *this;
}
void Vector::print()
{
    cout << "size = " << size << endl;
    for (int i = 0; i < size; ++i)
        cout << rep[i] << " ";
    cout << endl;
}
main.cpp

#include <iostream>
#include "Vector.h"
int main(int argc, const char * argv[])
{
    Vector v1;
    v1.print();
    
    int array[5] = {1, 2, 3, 4, 5};
    Vector v2 (array, 5);
    v2.print();
    
    Vector v3(v2);
    v3.print();
    Vector v5 = v2;
    v5.print();
    
    Vector v4;
    v4 = v3;
    v4.print();
    
    return 0;
}
运行结果:

默认构造函数

size = 0


非默认构造函数

size = 5

1 2 3 4 5 

重载构造函数

size = 5

1 2 3 4 5 

重载构造函数

size = 5

1 2 3 4 5 

默认构造函数

重载=

size = 5

1 2 3 4 5 

析构Vector

析构Vector

析构Vector

析构Vector

析构Vector

临时对象的系统开销很大,传值(包括参数、返回值)分别需要形参和返回值的临时对象调用拷贝构造函数和析构函数,传引用就显得效率,传参不需拷贝构造函数,返回时也不需要临时变量和析构。

B、测试何时调用拷贝构造函数

Demo.h

#ifndef __C__No731Class__Demo__
#define __C__No731Class__Demo__

#include <iostream>
using namespace std;
class Demo
{
private:
    int i;
public:
    Demo (int n = 0);
    Demo (const Demo & a);
    ~Demo();
    const Demo & operator = (const Demo & a);
};
#endif /* defined(__C__No731Class__Demo__) */
Demo.cpp

#include "Demo.h"
Demo::Demo (int n)
{
    i = n;
    cout << "默认构造函数" << endl;
}
Demo::Demo (const Demo & a)
{
    i = a.i;
    cout << "拷贝构造函数" << endl;
}
Demo::~Demo()
{
    cout << "析构Demo" << endl;
}
const Demo & Demo::operator = (const Demo & a)
{
    i = a.i;
    cout << "重载=" << endl;
    return * this;
}
main.cpp

#include "Demo.h"
Demo foo(Demo x)   //a传给x,拷贝构造函数
{
    Demo d;        //默认构造函数
    return d;      //开辟一个临时的形参空间Nu接收d,d传给Nu,拷贝构造函数(优化省略)
}
int main()
{
    Demo a (2);    //默认构造函数
    {
        Demo b;    //默认构造函数
        b = foo(a);//重载=,析构d,析构x
    }//析构b
    Demo c = a;    //拷贝构造函数
    return  0;     //析构c,析构a
}
运行结果:

默认构造函数

默认构造函数

拷贝构造函数

默认构造函数

重载=

析构Demo

析构Demo

析构Demo

拷贝构造函数

析构Demo

析构Demo


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值