+ -
当前位置:首页 → 问答吧 → 关于复制构造函数的作用

关于复制构造函数的作用

时间:2011-12-06

来源:互联网

C/C++ code
#include<iostream>
using namespace std;
class array
{ 
public:
    array(int n);
    ~array();
    array(array &c);
    int sum();
private:
    int *p;
    int number;
};
array::array(int n)
{
    number=n;
    p=new int[n];
    cout<<"please input "<<n<< " integer numbers:"<<endl;
    for(int i=0;i<n;i++)
        cin>>p[i];
}
array::array(array &c)
{
    number=c.number;
    p=new int[number];
    for(int i=0;i<number;i++)
        p[i]=c.p[i];
}
array::~array()
{delete []p;}
int array::sum()
{ int temp=0;
for(int i=0;i<number;i++)
temp+=p[i];
return temp;
}
int main()
{ 
    cout<<"please input array size:";
    int m;
    cin>>m;
    array a(m);
    cout<<"a sum is "<<a.sum()<<endl;
    array b(a);
    cout<<"b sum is "<<b.sum()<<endl;
    return 0;
}

在这个例子里,我看不出复制构造函数array(array &c);
有什么作用。他能完成的功能构造函数也能完成。
有人能举个例子,说明一下复制构造函数存在的必要吗?
什么时候需要用到复制构造函数?

作者: LAST_MAN   发布时间: 2011-12-06

如果你没有为你的程序添加一个拷贝构造函数,那么编译器也会向你的程序添加一个默认的拷贝构造函数.在一般情况下使用编译器的默认拷贝构造函数就可以了,但是如果你的类的成员数据有指针变量的存在,那么你最好自己构造一个拷贝构造函数,否则你的程序可能隐藏着许多错误.

作者: chenhuajie123   发布时间: 2011-12-06

那当然,拷贝构造函数和构造函数都是构造函数,都是用来创建新对象的,但是,拷贝构造函数创建新对象后,用另外一个对象的值来初始化了新创建的这个对象,而构造函数只是用一些默认值或者压根就没有初始化对象。拷贝构造函数就是为了使刚创建的对象的初始状态和另外一个已经存在的对象的状态一样。
就像你
array a1(n);
array copy_o(a1); //对象copy_o是个新对象,但是初始值和a1一样
而array a2(m);也是个新对象,但是值没有和别的对象一样,是一些默认值。

作者: yby4769250   发布时间: 2011-12-06

拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。

在C++中,下面三种对象需要调用拷贝构造函数:
  1) 一个对象以值传递的方式传入函数体;
  2) 一个对象以值传递的方式从函数返回;
  3) 一个对象需要通过另外一个对象进行初始化;

http://baike.baidu.com/view/1266959.htm

上边的意思是说,这个构造函数一般是编译器替你用。但另一个情况下也是用拷贝构造函数的:带参构造函数的初始化列表,一般是采用这种方法赋值

作者: zshtang   发布时间: 2011-12-06

聋子就没有耳朵了吗?

作者: mosal   发布时间: 2011-12-06

array a1;
array a2 = a1; // 复制构造
array a3(a1); // 复制构造

你如果不自己实现的话, 系统默认也会有的, 但是如果涉及到指针的话,默认的是浅拷贝(只复制指针地址)这样容易造成内存泄露等一些问题。所以有时候要自己实现。

作者: tujiaw   发布时间: 2011-12-06

http://topic.csdn.net/t/20060717/22/4886518.html

这个问题已经被讨论过一次

作者: zshtang   发布时间: 2011-12-06

拷贝构造如果用户不提供,那么编译器会自己合成一个
一般在类内部需要进行new操作来给数据成员分配空间的时候才用到自己定义的拷贝构造
例如:C/C++ code

#include <iostream>
using namespace std;
class base
{
    public:
    base():pt(NULL){}
    base(int *p):pt(new int(*p)){}
    //base(const base &orig):pt(new int(*orig.pt)){}
    //base& operator = (const base &orig)
    //{
     //   pt = new int(*orig.pt);
      //  return *this;
    //}
    int Get()const{return *pt;}
    ~base(){if(NULL != pt)delete pt;pt = NULL;}
    private:
    int *pt;
};
int main()
{
    int *p = new int(5);
    base mb1;
    {
        base mb2(p);
        mb1 = mb2;
    }
    cout << mb1.Get() << endl;
    delete p;
    return 0;
}

这个时候就需要提供自己定义的拷贝构造和赋值构造,因为如果你不提供,那么编译器合成的拷贝构造函数只是简单的执行pt = orig.pt操作,不会分配空间,那个对象类的指针成员都指向了同一块内存空间,那么其中一个对象析构之后,另一个对象的指针就变成了悬垂指针了,这样是很危险地,上面这段代码,你可以试试注释掉那几段代码和不注释掉之间的差异。

作者: qscool1987   发布时间: 2011-12-06