C++类对象的拷贝构造函数分析


对于普通类型的对象来说,它们之间的复制是很简单的,例如:

int a=100;
int b=a;

而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。下面看一个类对象拷贝的简单例子。

#include <iostream>
using namespace std;
class CA
{
 public:
  CA(int b)
  {
   a=b;
  }
  void Show ()
  {
   cout<<a<<endl;
  }
 private:
  int a;
};
int main()
{
 CA A(100);
 CA B=A;
 B.Show ();
 return 0;
}

运行程序,屏幕输出100。从以上代码的运行结果可以看出,系统为对象B分配了内存并完成了与对象A的复制过程。就类对象而言,相同类型的类对象是通过拷贝构造函数来完成整个复制过程的。下面我们举例说明拷贝构造函数的工作过程。

#include <iostream>
using namespace std;
class CA
{
 public:
  CA(int b)
  {
   a=b;
  }
  CA(const CA& C)
  {
   a=C.a;
  }
  void Show()
  {
   cout<<a<<endl;
  }
 private:
  int a;
};
int main()
{
 CA A(100);
 CA B=A;
 B.Show ();
 return 0;
}

CA(const CA& C)就是我们自定义的拷贝构造函数。可见,拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它的唯一的一个参数是本类型的一个引用变量,该参数是const类型,不可变的。例如:类X的拷贝构造函数的形式为X(X& x)。

当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:

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

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

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

如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝,后面将进行说明。

自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。

浅拷贝和深拷贝

在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如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;
}

http://www.lwinfo.com/uzt/list1/207177.html
http://www.lwinfo.com/uzt/list1/207672.html
http://www.lwinfo.com/uzt/list1/207673.html
http://www.lwinfo.com/uzt/list1/207675.html
http://www.lwinfo.com/uzt/list1/207677.html
http://www.lwinfo.com/uzt/list1/207678.html
http://www.lwinfo.com/uzt/list1/207679.html
http://www.lwinfo.com/uzt/list1/207680.html
http://www.lwinfo.com/uzt/list1/207682.html
http://www.lwinfo.com/uzt/list1/207684.html
http://www.lwinfo.com/uzt/list1/207686.html
http://www.lwinfo.com/uzt/list1/207689.html
http://www.lwinfo.com/uzt/list1/207690.html
http://www.lwinfo.com/uzt/list1/207693.html
http://www.lwinfo.com/uzt/list1/207695.html
http://www.lwinfo.com/uzt/list1/207696.html
http://www.lwinfo.com/uzt/list1/207698.html
http://www.lwinfo.com/uzt/list1/207701.html
http://www.lwinfo.com/uzt/list1/207702.html
http://www.lwinfo.com/uzt/list1/207706.html
http://www.lwinfo.com/uzt/list1/207707.html
http://user.qzone.qq.com/3055716359
http://t.qq.com/wfnpxyiyuan
http://user.qzone.qq.com/3055716359/blog/1429063798

时间: 2024-08-29 13:46:36

C++类对象的拷贝构造函数分析的相关文章

条款十一: 为需要动态分配内存的类声明一个拷贝构造函数和一个拷贝赋值运算符

看下面一个表示string对象的类: // 一个很简单的string类 class string { public: string(const char *value); ~string(); ... // 没有拷贝构造函数和operator= private: char *data; }; string::string(const char *value) { if (value) { data = new char[strlen(value) + 1]; strcpy(data, value

Android SO逆向-对象的拷贝构造函数

0x00 这一节我们主要讨论对象的拷贝构造函数的汇编实现. 0x01 我们直接看C++代码: Test.h: #ifndef _TEST_H_ #define _TEST_H_ #include <android/log.h> #define LOG_TAG "lesson5" #define ALOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) class Test

实现数组类(C++ 拷贝构造函数、拷贝函数)要判断赋值左右对象不相等,坑惨了

#include <iostream> using namespace std; class ArrayIndexOutOfBoundsException{ // 异常类 public: int index; ArrayIndexOutOfBoundsException(int k){ index = k; } }; class Array{ private: int *data; int size; static const int dSize = 10; // 数组默认大小 public:

含有指针变量的类需要重写拷贝构造函数,拷贝赋值函数,析构函数

编译器自带拷贝构造(ctor)和拷贝赋值函数(operator =), 但是对于成员变量含有指针的类,其不能使用默认的拷贝赋值函数.因为使用默认的,会直接将指针指向的地址进行赋值 (浅拷贝,共享内存,共指一个对象),而不是分配一块内存,具有相同的数值 (深拷贝,独立,两个对象). 浅拷贝容易造成dangling pointer. 用一个例子来展示: 1 #ifndef __MYSTRING__ 2 #define __MYSTRING__ 3 4 class String{ 5 public:

类string的拷贝构造函数与赋值函数

//参考高质量c++编程 复制构造函数 1 String ::String (const String &other) 2 { 3 4 5 int length=strlen(other.m_date); 6 //other对象的字符长度,其不包括‘\0’ 7 m_data=new char[length+1]; 8 //在堆上开辟一块内存,内存大小包括'\0' 9 strcpy(m_data, other.m_data); 10 11 } 赋值构造函数 1 String &String

Item 12:完整地拷贝对象(拷贝构造函数、复制运算符) Effective C++笔记

Item 12: Copy all parts of an object 在一个成熟的面向对象的C++系统中,只有两种拷贝对象的方式:复制构造函数和赋值运算符, 不妨称他们为拷贝函数. 拷贝函数属于编译器默认生成的函数(参考:Item 5:那些被C++默默地声明和调用的函数), 默认的拷贝函数确实会完整地拷贝对象,但有时我们选择重载拷贝函数,问题就出在这里! 一个正确拷贝函数的实现是这样的: class Customer{ string name; public: Customer::Custo

初学C++-----------------类的拷贝构造函数

拷贝构造函数能够使类具有自行赋值本类对象的能力,即可生成一个对象的副本,它只以本类对象的引用作为其唯一的形参,该函数的定义形式如下: class  类名 { public: 类名(形参)://(构造函数) 类名(类名  &对象名)://(拷贝构造函数) .................. }; 类名::类名(类名  &对象名)//拷贝构造函数的实现 { 函数体 } 拷贝构造函数举例: class Point { public: Point(int xx=0,int yy=0)   //构

C++ 拷贝构造函数和重载赋值操作符相互调用分析 [转]

结论: 从面相对象编程的角度考虑,拷贝构造函数调用重载赋值操作符,重载赋值操作符调用拷贝构造函数的写法都是没有意义的.应该避免. Don't try to implement one of the copying functions in terms of the other. Instead, put common functionality in a third function that both call. ——Effective C++ Third Edition By Scott M

【转】 c++拷贝构造函数(深拷贝,浅拷贝)详解

c++拷贝构造函数(深拷贝,浅拷贝)详解 2013-11-05 20:30:29 分类: C/C++ 原文地址:http://blog.chinaunix.net/uid-28977986-id-3977861.html 一.什么是拷贝构造函数      首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.  下面看一个类对象拷贝的简单例子. #include<iostream