c++基础概念之深浅拷贝
来源:互联网 发布:心知天气中文 编辑:程序博客网 时间:2024/06/08 10:35
0.拷贝构造函数
其实就是类与类之间的赋值操作所要调用的函数(因为类对象与普通对象不同,类对象内部结构较为复杂,存在各种成员变量)
代码举例:
#include<iostream>using namespace std;class Myclass { private: int a; public: //构造函数 Myclass(int b) { a = b;} //拷贝构造函数 Myclass(const Myclass& C) { a = C.a; } //一般函数 void Show () { cout<<a<<endl; } }; int main() { Myclass A(100); Myclass B = A; //Myclass B(A)也是一样的,调用拷贝构造函数,并不是简单的赋值 B.Show (); return 0; }
拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量。
1.深浅拷贝
浅拷贝
在对象赋值时,只对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝
代码举例:
#include<iostream>using namespace std;class Array{ public: Array(int t) { cout << "Array" << endl ; count = t ; } Array(const Array &temp) //尽可能的使用 const { cout << "~Array" << endl ; count = temp.count ; } void print() { cout << "count == " << count << endl; } private: int count;};int main(void){ Array My1(5); Array My2 = My1; My1.print(); My2.print();}
运行结果:
深拷贝
先来看下面的一个例子:
#include<iostream>using namespace std;class Array{ public: Array(int t) { cout << "Array" << endl ; count = t ; p = new int[count]; for(int i= 0;i != count ;++i) p[i] = i*i ; } Array(const Array &temp) //尽可能的使用 const { cout << "~Array" << endl ; count = temp.count ; p = new int[temp.count]; p = temp.p; //思考一下这里对不对?为什么不对?会发生什么? } void print() { cout << "count == " << count << endl; for(int i =0;i != count ;++i) cout << p[i] << endl ; //公有可以访问私有 } void printAddr() { cout << "p == " << p << endl ; } ~Array() { delete []p; p= NULL; } private: int count; int *p ; };int main(void){ Array My1(5); Array My2 = My1; My1.printAddr(); My2.printAddr(); My1.print(); My2.print();}
运行截图:
可以很明显的看到图中的报错“double free”。说明我们将一块内存 free了两次。产生了错乱!那么是什么原因引起的呐?
没错就是我们的拷贝构造函数,当我们写为p = temp.p; 就是将一个对象的p指针指向了传进来的temp.p的地址。那么他们两个对象的指针就指向了同一块内存,之后在析构函数中被free时,就会产生double free 。那么如何解决这个问题呐?
就是将传进来的temp 的每一块内存分别赋值给p,于是拷贝构造函数就成了这样:
Array(const Array &temp) { cout << "~Array" << endl ; count = temp.count ; p = new int[temp.count]; //p = temp.p; 是两个指针指向了同一块地址,delete 了两次 for(int i = 0 ;i< temp.count ;++i) p[i] = temp.p[i]; }
运行结果:
没错,这就是我们的深拷贝啦~_~
参考学习:参考学习
2.对象成员指针
所谓的对象成员指针就是指在一个类的成员中出现了另一个类的指针。
代码举例:
#include<iostream>using namespace std;class coordinate { //坐标点public: coordinate(int x,int y) { this->x= x; this->y =y; } ~coordinate() { } int getX() { return x; } int getY() { return y; }private: int x; int y;};class Line{ //许多个坐标点组成线段public: Line(int x1 ,int y1,int x2,int y2) { A = new coordinate(x1,y1); B = new coordinate(x2,y2); } void print() { cout << A->getX() << " " << A->getY() << endl ; cout << B->getX() << " " << B->getY() << endl ; } ~Line() { delete A; A=NULL; delete B; B=NULL; }private: coordinate *A; //对象成员指针 coordinate *B;};int main(void){// Line *p= new Line(1,2,3,4); Line *p; int *t; p= new Line(1,2,3,4); p->print(); delete p ; p= NULL; cout <<" t == " << sizeof(t)<< endl ; cout <<" p == " << sizeof(p)<< endl ; cout <<" sizeof(line1) == " << sizeof(Line)<< endl ; return 0;}
运行截图:
PS:不知道大家有木有注意到 sizeof 什么什么的那部分,在 64 位的机器中,一个指针占8个字节,那么请想上一想?为什么sizeof(line1)输出的是16呐?因为line对象中有两个指针coordinate 呀。哈哈哈
3.常对象成员与函数
常对象成员:就是用 const 来修饰的对象的数据成员对象,初始化时就只能用初始化列表来完成初始化。常成员函数就是用const来修饰成员函数,那么常成员函数中就不能修改数据成员的值了,因为:
void play() const //常成员函数的定义{ x= 10;}就等价于下面:void play(const Myclass *this){ this->x = 10; //!!!!}
显然给一个 const指针指向的数据成员赋值自然是错误的。还有:
void play() const;void play() ;
两个函数互为重载,但是这个只能说可以这样用,但绝对不会有人这样使用!!!!
如何调用常成员函数:
代码举例:
int main(void){ const Myclass Myclass(4);//常对象就会调用常成员函数}
PS:一般使用初始化列表就三种情况,
1.const成员的初始化2.有参构造的对象成员3.引用成员的初始化
4.常指针与常引用
就是下面的这两个东东:
const coordinate &My2 = My1; //常引用 const coordinate *p = &My1; //常指针
说明:与常对象相同,只能使用常成员函数,不能使用其他类型的函数
代码举例:
#include<iostream>using namespace std;class coordinate {public: coordinate(int x,int y) { this->x= x; this->y =y; } ~coordinate() { } int getX() //与下面的是不同的函数,但一般不这样书写 { } int getX() const //常成员函数,与上面的函数不冲突,但不建议这样写 { return x; } int getY() const { return y; } void printInfo() const //要求 this 指针只读 { cout << "liushengxi ----- " << endl; }private: int x; int y;};int main(void){ coordinate My1(1,2); const coordinate &My2 = My1; //常引用 const coordinate *p = &My1; //常指针 My2.getX(); //getX 要求this 是一个具有读写权限的对象,下同 p->getY(); return 0;}
阅读全文
0 0
- c++基础概念之深浅拷贝
- iOS基础之----深浅拷贝
- Objective-c 深浅拷贝
- 【C++】 浅析深浅拷贝
- C++String深浅拷贝
- Python之深浅拷贝
- C++之深浅拷贝
- C++之深浅拷贝
- Python之深浅拷贝
- 【C/C++】浅谈C/C++之深浅拷贝
- C++(笔记)深浅拷贝and静态static基础练习
- Objective-C 深浅拷贝学习
- [解析]Objective-C 深浅拷贝
- C++String深浅拷贝问题
- 浅析Objective-C 深浅拷贝
- c++-----string和深浅拷贝
- IOS学习之深浅拷贝
- iOS开发之深浅拷贝
- C语言hellowworld程序
- Android 内存优化简介
- BZOJ 2460 [BeiJing2011]元素 线性基入门
- POJ 2348 Euclid's Game(博弈)
- mysql-router 中间件的安装与配置
- c++基础概念之深浅拷贝
- [mongdb]安装mongodb和将mongdb设置为windows服务
- 2012-ImageNet数据集冠军AlexNet论文英文原文及AlexNet分析
- 【深度学习框架Caffe学习与应用】第四课 Caffe可视化工具
- 【BZOJ3294】放棋子(CQOI2011)-DP+组合数学
- 关于自定义TextView的测量问题
- C++中不应该返回局部变量的地址
- HTTP协议
- 图解机器学习