C++中拷贝构造函数

C++中拷贝构造函数

1.什么是拷贝构造函数:

拷贝构造函数嘛,当然就是拷贝和构造了。(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数。百度百科上是这样说的:拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。其唯一的参数(对象的引用)是不可变的(const类型)。此函数经常用在函数调用时用户定义类型的值传递及返回

2.拷贝构造函数的形式

Class X

{

public:

  X();

  X(const X&);//拷贝构造函数

}

2.1为什么拷贝构造参数是引用类型?

其原因如下:当一个对象以传递值的方式传一个函数的时候,拷贝构造函数自动被调用来生成函数中的对象(符合拷贝构造函数调用的情况)。如果一个对象是被传入自己的拷贝构造函数,它的拷贝构造函数将会被调用来拷贝这个对象,这样复制才可以传入它自己的拷贝构造函数,这会导致无限循环直至栈溢出(Stack Overflow)。

3.拷贝构造函数调用的三种形式

3.1.一个对象作为函数参数,以值传递的方式传入函数体;

3.2.一个对象作为函数返回值,以值传递的方式从函数返回;

3.3.一个对象用于给另外一个对象进行初始化(常称为复制初始化)。

总结:当某对象是按值传递时(无论是作为函数参数,还是作为函数返回值),编译器都会先建立一个此对象的临时拷贝,而在建立该临时拷贝时就会调用类的拷贝构造函数

4.深拷贝和浅拷贝

如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。(位拷贝又称浅拷贝,后面将进行说明。)自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。

在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。事实上这就要用到深拷贝了,要自定义拷贝构造函数。

深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。下面举个深拷贝的例子。

#include <iostream>

using namespace std;

class CA

{

public:

  CA(int b,char* cstr)

  {

    a=b;

     str=new char[b];

    strcpy(str,cstr);

  }

  CA(const CA& C)

  {

    a=C.a;

    str=new char[a]; //深拷贝

    if(str!=0)

     strcpy(str,C.str);

  }

  void Show()

  {

    cout<<str<<endl;

  }

  ~CA()

  {

    delete str;

  }

 private:

   int a;

   char *str;

};

int main()

{

  CA A(10,"Hello!");

  CA B=A;

  B.Show();

  return 0;

}

浅拷贝资源后在释放资源的时候会产生资源归属不清的情况导致程序运行出错。一定要注意类中是否存在指针成员。

5.拷贝构造函数与“=“赋值运算符

例如:

class CExample

{}

int main()

{

CExample e1 = new CExample;

CExample e2 = e1;//调用拷贝构造函数

CExample e3(e1);//调用拷贝构造函数

CExample e4;

e4 = e1;//调用=赋值运算符

}

通常的原则是:①对于凡是包含动态分配成员或包含指针成员的类都应该提供拷贝构造函数;②在提供拷贝构造函数的同时,还应该考虑重载"="赋值操作符号。

时间: 2024-10-07 18:15:15

C++中拷贝构造函数的相关文章

C++中拷贝构造函数和赋值函数被调用的时机

一.拷贝构造函数被调用的时机: 1. 当用类的一个对象去初始化该类的另一个对象(或引用)时系统自动调用拷贝构造函数实现拷贝赋值. 2. 若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数. 3. 当函数的返回值是类对象时,系统自动调用拷贝构造函数. 二.赋值函数被调用的时机: 当用一个对象赋值给另一个对象时 注意一.二中初始化和赋值的区别 C++中拷贝构造函数和赋值函数被调用的时机,布布扣,bubuko.com

c++中 拷贝构造函数的深拷贝和浅拷贝--“浅拷贝”与“深拷贝”

C++中对象的复制就如同"克隆",用一个已有的对象快速地复制出多个完全相同的对象.一般而言,以下三种情况都会使用到对象的复制: (1)建立一个新对象,并用另一个同类的已有对象对新对象进行初始化,例如: class Rect { private: int width; int height; }; Rect rect1; Rect rect2(rect1); // 使用rect1初始化rect2,此时会进行对象的复制 (2)当函数的参数为类的对象时,这时调用此函数时使用的是值传递,也会产

C++ 拷贝构造函数之const关键字

class Complex { public: //拷贝构造函数1 Complex(const Complex &c); //拷贝构造函数2 Complex(Complex &c); private: double m_real; double m_imag; } 上面例子中拷贝构造函数1才是系统默认的拷贝构造函数,在自己写的代码中这两个拷贝构造函数都没有什么问题,但是如果用于stl模板参数时,第二个拷贝构造函数往往会出现一些莫名其妙的错误,为了谨慎起见,以后拷贝构造函数的参数都用cons

C++中关于拷贝构造函数的使用问题?

奉庵耪 C++中关于拷贝构造函数的使用问题?

C++中构造函数,拷贝构造函数,析构函数

C++中默认构造函数就是没有形参的构造函数.准确的说法,按照<C++ Primer>中定义:只要定义一个对象时没有提供初始化式,就是用默认构造函数.为所有 的形参提供默认实参的构造函数也定义了默认构造函数. 合成的默认构造函数,即编译器自动生成的默认构造函数.<C++ Primer>中的说明:一个类哪怕只定义了一个构造函数,编译器也不会再生成默认构造函数.这条规则的根据是,如果一个类再某种情况下需要控制对象初始化,则该类很可能在所有情况下都需要控制.只有当一个类没有定义构造函数时,

关于 C++ 拷贝构造函数(copy constructor)中的形参必须为引用类型的详解

在<C++ primer>中文第四版中,关于拷贝构造函数(也称复制构造函数)是这样定义的:是一种特殊构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用. 问题来了!为什么形参必须为该类类型的引用?而不能是值传递方式?(PS:其实传值和传址都可以统一为传值,前者传的是对象的值,后者传的是对象的地址的值) 先看下边两组代码: 1. 1 class Example { 2 3 public: 4 5 Example() {} 6 7 Example(const Example&a

在拷贝构造函数中为什么可以访问引用对象的私有变量? [问题点数:0分]

在拷贝构造函数中为什么可以访问引用对象的私有变量? 例如: class Point { public:         Point(int xx=0,int yy=0){X=xx;Y=yy;}         Point(Point &p); private:         int X,Y; }; Point::Point(Point &p) {         X=p.X;         Y=p.Y; } 更多 0 分享到: 相关主题推荐: 对象 class yy x 相关帖子推荐:

C++中 简单查看临时对象,局部对象的生命周期,及拷贝构造函数(测试代码)

#include <iostream> using namespace std; class A {     public: A(int a = 5) {     cout<<"A constructor "<<this<<endl; } ~A() {     cout<<"A destructor "<<this<<endl; } A(const A & r) {     

关于C++ 中 thread 的拷贝构造函数

起因来自于<C++并发编程实战>的这样一个例子 #include <thread> #include <iostream> #include <stdexcept> class ScropeThread { public: ScropeThread(std::thread t) :m_pThead(std::move(t)) { if (!m_pThead.joinable()) { throw std::logic_error("no threa