拷贝构造函数

转载 2007年09月29日 16:14:00
copy构造函数
[功能] 当类中包含动态分配成员,用于将已有对象初始化另一个对象的情况下应提供拷贝构造函数,同时还应提供operator=重载


1)COPY构造函数只有在对象声明和用另一个对象初始化它同时发生时才调用,也就是, ClassName objA= objB;时才调用copy构造函数,

而如
A objA, objB;  的声明形式
  ...
  ObjB=ObjA;   //这个时候只调用 operator=()函数,而不调用copy构造函数



2)当对象直接作为参数传给函数时,函数将建立对象的临时拷贝,这个拷贝过程也将调同拷贝构造函数。

BOOL func(ClassName obj)
{
       //针对obj的操作实际上是针对复制后的临时拷贝进行的
}

ClassName objA;

func(objA);   //对象直接作为参数。


3)当函数中的局部对象被被返回给函数调者时,也将建立此局部对象的一个临时拷贝,拷贝构造函数也将被调用

ClassName  func()
{
     ClassName  obj;
     return  obj;      //返回值
}



[示例]
class A{
   public:
      A()
      {
         name=NULL;
         age=20;
      }

      void Init(int size, int age)
      {
          name=new char[size];  //动态分配内存
          this.age=age;
      }    

      int getAge()
      {
          return age;
      }

   private:
      char *name;  //类的对象中包含指针成员,指向动态分配的内存资源 (即指向堆中分配的一段内存空间)
      int  age;
};
      

生成一个对象:
A objA;
objA.Init(20, 45);


A objB=objA;       //这时用objA初始化objB, 即必须把objA内的数据成员值赋给objB的数据成员
                 //即 objB.name <= objA.name;      objB.age <=  objA.age;

由于默认的没有拷贝构造函数的情况下会直接 objB.name=objA.name;  所以这时objB.name和objA.name同时指一个堆内存区域,从而产生了对象的内存不独立的情况


要想避免这种情况的发生必须我们自己指定数据拷贝的方式, 这就需要自己制作copy构造函数  
类名(const 类名& RightSide){
  //...
}


我们这里的定义方式如下

class A{
   public:
      A()
      {
         name=NULL;
         age=20;
      }

      A(const A& RightSide);

      void Init(int size, int age)
      {
          this.size=size;
          name=new char[size];  //动态分配内存
          this.age=age;
      }    

      int getAge()
      {
          return age;
      }

   private:
      char *name;  //类的对象中包含指针成员,指向动态分配的内存资源 (即指向堆中分配的一段内存空间)
      int  size;    
      int  age;
      
};

A::A(const A&  RightSide)
{
   age=RightSide.age;     //对于int, float, char, double, bool 等内置类型的成员,直接用=号复制即可
   size=RightSide.size;

   name=new char[size];
   memcpy(name, RightsSide.name, size*sizeof(char));
}



1)无拷贝构造函数:

#include

using namespace std;

class A
{
   public:
      A()
      {
         str=NULL;
      }

      ~A()
      {
          cout<<"~A()"<
          //delete str;
      }


      void Init(int size,  char *str);

      char *getStr()
      {
          return str;
      }

      void setStr(char *str)
      {
          strncpy(this->str,str,size);
      }

   private:
      char *str;  //类的对象中包含指针成员,指向动态分配的内存资源 (即指向堆中分配的一段内存空间)
      int  size;
};

void A::Init(int size, char *str)
{
   this->size=size;   //因为this是A *this指针, 所以要用this->size而不是this.size
   this->str=new char[size];
   strncpy(this->str, str, size);
}


int main()
{
    A objA;  //调用构造函数A()

    objA.Init(20,"yaoshuyin");
    cout<<"After init: "<
    cout<<"objA Str: "<<//输出: yaoshuyin

    A objB=objA;
    cout<<"After objB=objA: "<
    cout<<"objA Str: "<<"  "<<//输出: yaoshuyin
    cout<<"objB Str: "<<"  "<<//输出: yaoshuyin

    objA.setStr("test");  //设置objA的str值为test
    cout<<"objA Str: "<<<"  "<<//输出: test
    cout<<"objB Str: "<<<"  "<<//输出: test  //可见objA.str和objB.str指向了同一块堆内存

    return 0;
}



2)有拷贝构造函数

#include

using namespace std;

class A
{
   public:
      A()
      {
         //str=NULL;
      }
      ~A()
      {
          cout<<"~A()"<
          try{
              //delete[] str;
          }
          catch(...)
          {
          }
      }

     A(const A& RightSide);

      void Init(int size,  char *str);

      char *getStr()
      {
          return str;
      }

      void setStr(char *str)
      {
          strncpy(this->str,str,size);
      }

   private:
      char *str;  //类的对象中包含指针成员,指向动态分配的内存资源 (即指向堆中分配的一段内存空间)
      int  size;
};

void A::Init(int size, char *str)
{
   this->size=size;   //因为this是A *this指针, 所以要用this->size而不是this.size
   this->str=new char[size];
   strncpy(this->str, str, size);
}


A::A(const A&  RightSide)
{
   cout<<"正在调用copy构造函数"<
   size=RightSide.size;
   this->str=new char[size];
   memcpy(this->str, RightSide.str, size*sizeof(char));
}

int main()
{
    A objA;  //调用构造函数A()

    objA.Init(20,"yaoshuyin");
    cout<<"After init: "<
    cout<<"objA Str: "<<//输出: yaoshuyin

    A objB=objA;     //注意这里的形式 A objB = objA;
    cout<<"After objB=objA: "<
    cout<<"objA Str: "<<&objA.str<<"  "<<//输出: yaoshuyin
    cout<<"objB Str: "<<&objB.str<<"  "<<//输出: yaoshuyin

    objA.setStr("test");
    cout<<"objA Str: "<<<"  "<<//输出: test
    cout<<"objB Str: "<<<"  "<<//输出: yaoshuyin   //因为copy构造函数 A::A(const A& RightSide) ,中的this->str=new char[size]; 使objB.str指向了一块新的堆内存,所以objA.str和objB.str各自指向不同的内存

    return 0;
}


3)A objA, objB;  的声明形式,是不会调用copy构造函数的, 因为copy构造函数只有在
对象声明和用另一个对象初始化它同时发生时才调用,也就是, ClassName objA= objB;时才调用copy构造函数,

如A objA, objB;
  ...
  ObjB=ObjA;  //这个时候只调用 operator=()函数,而不调用copy构造函数

#include

using namespace std;

class A
{
   public:
      A()
      {
         //str=NULL;
      }
      ~A()
      {
          cout<<"~A()"<
          try{
              //delete[] str;
          }
          catch(...)
          {
          }
      }

      A(const A& RightSide);

      void Init(int size,  char *str);

      char *getStr()
      {
          return str;
      }

      void setStr(char *str)
      {
          strncpy(this->str,str,size);
      }

   //private:
      char *str;  //类的对象中包含指针成员,指向动态分配的内存资源 (即指向堆中分配的一段内存空间)
      int  size;
};

void A::Init(int size, char *str)
{
   this->size=size;   //因为this是A *this指针, 所以要用this->size而不是this.size
   this->str=new char[size];
   strncpy(this->str, str, size);
}


A::A(const A&  RightSide)
{
   cout<<"正在调用copy构造函数"<
   size=RightSide.size;
   this->str=new char[size];
   memcpy(this->str, RightSide.str, size*sizeof(char));
}

int main()
{
  
    A objA;

    A objB;  //调用构造函数A()
    /*
     * 或
    *  A objA, objB;
    */

    objA.Init(20,"yaoshuyin");
    cout<<"After init: "<
    cout<<"objA Str: "<<//输出: yaoshuyin

    objB=objA;
    cout<<"After objB=objA: "<
    cout<<"objA Str: "<<&objA.str<<"  "<< //输出: yaoshuyin
    cout<<"objB Str: "<<&objB.str<<"  "<< //输出: yaoshuyin


    cout<<
    objB.setStr("test");
    cout<<"objA Str: "<<<"  "<<//输出: test
    cout<<"objB Str: "<<<"  "<< //输出: test


    return 0;
}
 

相关文章推荐

C++中拷贝构造函数的使用

  • 2012-07-29 08:56
  • 275KB
  • 下载

拷贝构造函数

  • 2014-03-10 22:22
  • 34KB
  • 下载

C++拷贝构造函数详解

一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: [c-sharp] view plaincopy ...

C++ 拷贝构造函数(转)

C++ 拷贝构造函数(转)对于普通类型的对象来说,他们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象和普通对象不同,类对象内部结构一般较为复杂,存在各...

拷贝构造函数..........

拷贝构造函数的参数类型必须是引用

原文:http://blog.csdn.net/hackbuteer1/article/details/6545882

析构函数和拷贝构造函数

  • 2012-08-30 13:16
  • 131KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)