C++类对象的拷贝构造函数分析-阿里云开发者社区

开发者社区> andyro1984> 正文

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

简介:  对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100;int b=a;   而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。
+关注继续查看

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

int a=100;
int b=a;

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

#include <iostream>
using namespace std;
class CA
{
 public:
  CA(int b)
  
  void Show ()
  
 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)
  
  CA(const CA& C)
  
  void Show()
  
 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()
  
  ~CA()
  {
   delete str;
  }
 private:
  int a;
  char *str;
};

int main()
{
 CA A(10,"Hello!");
 CA B=A;
 B.Show();
 return 0;
}

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
六十一条面向对象分析设计的经验原则
你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚。但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起 。   ----- Arthur J.Riel   (1)所有数据都应该隐藏在所在的类的内部。
721 0
将成员函数用作可调用对象
19.18编写一个函数,使用count_if统计在给定的vector中有多少个空string。 #include #include #include #include #include using namespace std; int main() { vector...
489 0
UML面向对象分析与建模-【6】状态图
一、概述 在一般的面向对象技术中,状态图又称为状态迁移图。描述了一个特定对象的所有可能状态以及由于各种事件的发生而引起的状态之间的迁移。大多数面向对象技术都使用状态图来描述一个对象在其生命周期中的行为。
652 0
C++函数对象
  原文:http://blog.csdn.net/ggggqqqqihc/article/details/1727020   标准库里的count_if可以统计容器中满足特定条件的元素的个数。例如要统计一个整数vector——ivec中正数的个数,可以先写一个返回类型为bool,含有一个int参数的条件函数: bool pred(int val){ return val>0; }    之后可以用count_if(ivec.begin(),ivec.end(),pred)计算出正整数的个数。
484 0
对象,函数作为一个函数的参数
1 2 3 4 5 对象,函数作为一个函数的参数 6 7 8 9 //1.将一个对象传给一个函数 10 function $$(id){ 11 return document.
615 0
Angular Component template函数执行上下文的对象
Angular Component template函数执行上下文的对象
5 0
基于对象存储 OSS 的智能数据分析处理框架和功能
今年参加了 2019 全球闪存峰会(Flash Memory World),分享了“基于云存储的智能数据分析处理架构”,重点介绍在对象存储 OSS 之上的数据处理功能,现整理相关内容和大家探讨。
2131 0
+关注
andyro1984
本团队有11年以上的解决方案端到端开发经验,涉及的行业有云计算、应用软件(包括WEB)、嵌入式、分布式、大型服务程序(Windows/Linux)、操作系统等。
211
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载