1、一般构造函数
如果没有提供任何构造函数,创建一个什么都不做的构造函数
如:
test::test()
{}
如果希望编译器不使用这种默认的构造函数
可以自己定义默认构造函数
test::test()
{
  ...........;
}
当然也可以自己传入值定义构造函数
test::test(const char* tin)
{
  ...........;
}

2、复制构造函数
它用于将一个对象复制到一个新创建的对象中,类的复制构造函数原型如下:
class_name(const class_name &);
关于复制构造函数下面几种情况会使用到:
test my1(my); 显示调用,my1是和my一样的副本
test my1 = test(my); 显示调用,my1是和my一样的副本
test my1 = my; 隐试调用,my1是和my一样的副本
void tf1(test t1);函数传值生成临时的类对象在函数中使用
test *p = new test(my);未测试
简单的说程序生成了对象的副本,编译器都会使用复制构造函数;既然是副本我们可以想象如果
类中定义的是指针类型,那么指针指向的是同一片位置。如果此时调用析构函数会重复的释放
同一片内存区域,同时如果不定义复制构造函数,那么某些计数器将不你能正常工作。

另外我们注意同一段函数中如果类中有静态对象如下:
private:
static int num_s;
使用
int charin::num_s = 0; 
那么在调用这个类的函数中多次调用它使用值是共享的因为是同一块内存区域。这个其实和一般
的静态内部变量没什么两样

我们来看一段代码

点击(此处)折叠或打开

  1. ::::::::::::::
  2. c2.h
  3. ::::::::::::::
  4. /*************************************************************************
  5. > File Name: c2.h
  6. > Author: gaopeng
  7. > Mail: gaopp_200217@163.com
  8. > Created Time: Fri 24 Jun 2016 01:47:19 AM CST
  9. ************************************************************************/
  10. #include<iostream>
  11. using namespace std;
  12. class charin
  13. {
  14. private:
  15. static int num_s;
  16. char* sin;
  17. int len;
  18. public:
  19. charin(void);
  20. charin(const char *);
  21. //charin(charin &);
  22. ~charin(void);
  23. friend std::ostream & operator<<(std::ostream &,const charin &);
  24. };
  25. ::::::::::::::
  26. cf.cpp
  27. ::::::::::::::
  28. /*************************************************************************
  29. > File Name: cf.cpp
  30. > Author: gaopeng
  31. > Mail: gaopp_200217@163.com
  32. > Created Time: Fri 24 Jun 2016 01:59:13 AM CST
  33. ************************************************************************/
  34. #include<iostream>
  35. #include<string.h>
  36. #include"c2.h"
  37. using namespace std;
  38. int charin::num_s = 0;
  39. charin::charin(void)
  40. {
  41. len = strlen("study c++")+1;
  42. cout << len <<" mem alloc!"<<endl;
  43. sin = new char[len];
  44. strcpy(sin,"study c++");
  45. num_s++;
  46. cout << sin <<" in "<<num_s<<endl;
  47. }
  48. charin::charin(const char* sorstr )
  49. {
  50. len = strlen(sorstr)+1;
  51. cout << len <<" bytes mem alloc!"<<endl;
  52. sin = new char[len];
  53. strcpy(sin,sorstr);
  54. num_s++;
  55. cout << sin <<" in "<<num_s<<endl;
  56. }
  57. charin::~charin(void)
  58. {
  59. num_s--;
  60. cout << len <<" bytes mem release!"<<endl;
  61. cout << sin <<" out "<<num_s<<endl;
  62. delete [] sin;
  63. }
  64. std::ostream & operator<<(std::ostream & os,const charin & cin)
  65. {
  66. os << cin.sin;
  67. return os;
  68. }
  69. ::::::::::::::
  70. main.cpp
  71. ::::::::::::::
  72. /*************************************************************************
  73. > File Name: main.cpp
  74. > Author: gaopeng
  75. > Mail: gaopp_200217@163.com
  76. > Created Time: Fri 24 Jun 2016 02:23:51 AM CST
  77. ************************************************************************/
  78. #include<iostream>
  79. #include"c2.h"
  80. using namespace std;
  81. void chmi(charin );
  82. int main(void)
  83. {
  84. const char *testc = "test123";
  85. charin t1;
  86. cout <<"test"<<endl;
  87. charin t2(testc);
  88. charin t3 = t2; //error
  89. chmi(t2); //error
  90. }
  91. //error beacause pointer sin pointer same point;
  92. void chmi(charin a)
  93. {
  94. cout<<"test here: "<<a<<endl;
  95. }

这段程序报错如下:
gaopeng@bogon:~/CPLUSPLUS/part11/c2$ ./a.out 
10 mem alloc!
study c++ in 1
test
8 bytes mem alloc!
test123 in 2
test here: test123
8 bytes mem release!
 out 1
*** Error in `./a.out': double free or corruption (fasttop): 0x00000000021c1030 ***
Aborted (core dumped)

我使用的LINUX g++编译器,可以看报错double free or corruption,重复的释放,其实这里的计数器num_s也不能正常工作。
这种情况下我们必须要自己定义复制构造函数,使用深度复制而不是简单的为指针类型数据复制指针的指向而已。
我们在程序中加入:

点击(此处)折叠或打开

  1. c2.h 加入
  2. #include<iostream>
  3. using namespace std;
  4. class charin
  5. {
  6. private:
  7. ..........
  8. public:
  9. ..........
  10. charin(charin &); //加入
  11. .........
  12. };
     
     cf.cpp加入新函数 复制构造函数
  1. charin::charin(charin &in)
  2. {
  3. len = in.len;
  4. sin = new char[len];
  5. strcpy(sin,in.sin);
  6. num_s++;
  7. cout << len <<" bytes mem alloc!"<<endl;
  8. cout << sin <<" deep copy in "<<num_s<<endl;
  9. }

接着我们再来跑一下我们的程序
10 mem alloc!
study c++ in 1
test
8 bytes mem alloc!
test123 in 2
8 bytes mem alloc!
test123 deep copy in 3
8 bytes mem alloc!
test123 deep copy in 4
test here: test123
8 bytes mem release!
test123 out 3
8 bytes mem release!
test123 out 2
8 bytes mem release!
test123 out 1
10 bytes mem release!
study c++ out 0

没有问题了。

---endl---

C++再议构造函数及复制构造函数深度复制相关推荐

  1. javascript 数组和对象的浅复制和深度复制 assign/slice/concat/JSON.parse(JSON.stringify())...

    javascript 数组和对象的浅度复制和深度复制 在平常我们用 '='来用一个变量引用一个数组或对象,这里是'引用'而不是复制下面我们看一个例子引用和复制是什么概念 var arr=[1,2,3, ...

  2. C#复制和深度复制的实现方法

    深度复制与浅表复制的区别在于,浅表复制只复制值类型的值,而对于实例所包含的对象依然指向原有实例. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2 ...

  3. java 对象深度复制_Java深度复制– Java复制对象

    java 对象深度复制 Today we will look into Java deep copy. Sometimes we want to get a copy of an Object, bu ...

  4. 构造函数和复制函数java_用Java复制构造函数

    构造函数和复制函数java Copy Constructor in java class is a special type of constructor that takes same class ...

  5. vue clone html,Vue.js之slot深度复制详解

    前言 在Vue中,slot是一个很有用的特性,可以用来向组件内部插入一些内容.slot就是"插槽"的意思,用大白话说就是:定义组件的时候留几个口子,由用户来决定插入的内容. 例如我 ...

  6. ❥关于C++之类的复制构造函数赋值运算符

    C++自动提供了下面这些成员函数: 默认构造函数,如果没有定义构造函数 默认析构函数,如果没有定义 复制构造函数,如果没有定义 赋值运算符,如果没有定义 地址运算符,如果没有定义 一.复制构造函数 复 ...

  7. 复制构造函数(拷贝构造函数)

    也许很多C++的初学者都知道什么是构造函数,但是对复制构造函数(copy constructor)却还很陌生.对于我来说,在写代码的时候能用得上复制构造函数的机会并不多,不过这并不说明复制构造函数没什 ...

  8. C++深复制(深拷贝)、浅复制(浅拷贝)和复制构造函数(拷贝构造函数)详解+实例

    转载出处:https://blog.csdn.net/sxhelijian/article/details/23209967 对象的复制 对于普通类型的对象来说,它们之间的复制是很简单的,例如: in ...

  9. 复制构造函数 与 赋值函数 的区别

    构造函数.析构函数.赋值函数是每个类最基本的的函数.每个类只有一个析构函数和一个赋值函数.但是有很多构造函数(一个为复制构造函数,其他为普通构造函数.对于一个类A,如果不编写上述四个函数,c++编译器 ...

最新文章

  1. TCP 网络应用程序开发流程
  2. R语言replace函数数值替换实战
  3. 搭建免费ftp服务,视频演示
  4. 原型 - 实现自己的jQuery
  5. web前端安全编码(模版篇)
  6. Node mysql mvc vue_net MVC +Vue.js+Element UI 笔记
  7. * poj 1251 JungleRoad 最小生成树 Kruskal算法、Prim算法
  8. tensorflow 显存 训练_tensorflow手动指定GPU以及显存大小
  9. Django学习-22-Form
  10. [读书笔记]普林斯顿微积分读本(修订版)-未完工
  11. [LeetCode] 682. Baseball Game 棒球游戏
  12. session的活化和钝化
  13. 3D建模:14个建模小技巧
  14. filebeat7.7.0相关详细配置预览- Setup ILM
  15. 赞!走心推荐这几个 BAT 大佬的公众号
  16. 归并排序(Python)
  17. 正确使用GCC inline assemble 中的 clobber
  18. 华清远见第一周学习体会
  19. linux文件属性详细说明(网络转载,仅供学习之用)
  20. Python综合评价模型(三)秩和比法

热门文章

  1. Mysql中的一绡规范约束,摘自《阿里巴巴 Java 开发手册》
  2. ThinkPHP验证码不能显示如何解决
  3. 很简单的事情不细心,就可能导致很大的麻烦,然后花费好几倍的人力物力时间和弥补该“小问题”;
  4. SpringBoot @CachePut注解的使用原理
  5. Rust性能分析-迭代器的enumerate方法是否会影响程序性能
  6. 装修时水电如何开槽?沟槽如何封堵?有哪些防止沟槽开裂的方法
  7. linux下golang编译环境搭建
  8. cshtml的a标签跳转页面_朋友圈标签来了!热门流量关键词带动视频号、小程序、搜一搜...
  9. springboot整合mongodb changestream
  10. jdbc连接mysql问题