3.5.3 拷贝构造函数
代码示例:
#include<iostream>
#include<string>
#include<stdlib.h>
#include"Teacher.h"
using namespace std;
int main()
{
Teacher t1;
Teacher t2=t1;
Teacher t3(t1);
system("pause");
return 0;
}
Teacher.h
#include<iostream>
#include<string>
using namespace std;
class Teacher
{
public:
Teacher(string name ="Jim", int age=15);
Teacher(const Teacher&tea);
void setName(string _name);
string getName();
void setAge(int _age);
int getAge();
private:
string m_strName;
int m_iAge;
};
Teacher.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Teacher.h"
using namespace std;
Teacher::Teacher(string name, int age) :m_strName(name), m_iAge(age)//, m_iMax(m)
{
cout << "Teacher(string name,int age)" << endl;
}
Teacher::Teacher(const Teacher&tea)
{
cout << "Teacher(const Teacher&tea)" << endl;
}
3.6 析构函数
定义格式:~类名()
唯一功能就是释放内存,所以不能设置参数,没有返回值,不能重载
若没有自定义则系统自动生成
在对象销毁时自动调用
class student
{
public:
student(){cout<<"student"<<endl;}
~student(){cout<<"~student"<<endl;}
private:
string m_strName;
};
对象的生命历程
对象实例化时——1.先向系统申请内存——初始化列表——构造函数——参与运算——析构函数——释放内存
代码示例:
/*定义一个Teacher类,具体要求如下:
1.自定义析构函数
2.普通方式实例化的对象,在销毁对象时是否自动调用析构函数
3.通过拷贝构造函数实例化对象,在销毁对象时是否自动调用析构函数
数据成员:
姓名:name
年龄:age
成员函数:
数据成员的封装函数 */
#include<iostream>
#include<string>
#include<stdlib.h>
#include"Teacher.h"
using namespace std;
int main()
{
Teacher t1;
Teacher t2(t1);
system("pause");
return 0;
}
Teacher.h
#include<iostream>
#include<string>
using namespace std;
class Teacher
{
public:
Teacher(string name ="Jim", int age=15);
Teacher(const Teacher&tea);
~Teacher();
void setName(string _name);
string getName();
void setAge(int _age);
int getAge();
private:
string m_strName;
int m_iAge;
};
Teacher.cpp
#include<stdlib.h>
#include<string>
#include"Teacher.h"
using namespace std;
Teacher::Teacher(string name, int age) :m_strName(name), m_iAge(age)//, m_iMax(m)
{
cout << "Teacher(string name,int age)" << endl;
}
Teacher::Teacher(const Teacher&tea)
{
cout << "Teacher(const Teacher&tea)" << endl;
}
Teacher::~Teacher()
{
cout << "~Teacher()" << endl;
system("pause");
}
总结:
类:数据成员和成员函数组成(
担心自己的类与其他人的类同名,可以在此之上定义自己的命名空间)
3.7 对象数组
代码示例:
/*定义一个Coordinate类,具体要求如下:
数据成员:
m_iX
m_iY
分别从栈和堆中实例化长度为3的对象数组
给数组中的元素分别赋值
遍历两个数组 */
#include<iostream>
#include<string>
#include<stdlib.h>
#include"Coordinate.h"
using namespace std;
int main()
{
Coordinate Coor[3];
Coor[0].m_iX = 3;
Coor[0].m_iY = 5;
Coordinate *p = new Coordinate[3];
p->m_iX = 7;
p[0].m_iY = 9;
p++;
p->m_iX = 11;
p[0].m_iY = 13;
p[1].m_iX = 15;
p++;
p->m_iY = 17;
for (int i = 0; i < 3; i++)
{
cout << "coor_x"<<Coor[i].m_iX << endl;
cout << "coor_y" << Coor[i].m_iY << endl;
}
for (int j = 0; j < 3; j++)
{
cout << "p_x" << p->m_iX << endl;
cout << "p_y" << p->m_iY << endl;
p--;
}
p++;
delete[]p;
p = NULL;
system("pause");
return 0;
}
Coordinate.h
#include<iostream>
#include<string>
using namespace std;
class Coordinate
{
public:
Coordinate();
~Coordinate();
public:
int m_iX;
int m_iY;
};
Coordinate.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Coordinate.h"
using namespace std;
Coordinate::Coordinate()
{
cout << "Coordinate();" << endl;
}
Coordinate::~Coordinate()
{
cout << "~Coordinate();" << endl;
system("pause");
}
注:此处 int m_iX 说明数据成员时把public顺手写成了private,导致后面的直接实例化不成功,private 要通过set 和get函数才能实例化
且,里面p指针指向的内存问题需要注意,写起来较为复杂。
3.8对象成员
/*对象成员
要求:
定义两个类:
坐标类:Coordinate
数据成员:m_iX,m_iY
成员函数:构造函数,析构函数,数据封装函数
线段类:Line
数据成员:点A m_coorA,点B m_coorB
成员函数:构造函数,析构函数,数据封装函数,信息打印函数 */
#include<iostream>
#include<string>
#include<stdlib.h>
#include"Line.h"
using namespace std;
int main()
{
Line *p = new Line(1,2,3,4);
p->print();
delete p;
p = NULL;
system("pause");
return 0;
}
Coordinate.h
#include<iostream>
#include<string>
using namespace std;
class Coordinate
{
public:
Coordinate(int x,int y);
~Coordinate();
void setA(int x);
int getA();
void setB(int y);
int getB();
public:
int m_iX;
int m_iY;
};
Coordinate.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Coordinate.h"
using namespace std;
Coordinate::Coordinate(int x,int y)
{
m_iX = x;
m_iY = y;
cout << "Coordinate()" << m_iX<<" "<<m_iY<<endl;
}
Coordinate::~Coordinate()
{
cout << "~Coordinate();" << m_iX << " " << m_iY<< endl;
}
void Coordinate:: setA(int x)
{
m_iX = x;
}
int Coordinate::getA()
{
return m_iX;
}
void Coordinate::setB(int y)
{
m_iY = y;
}
int Coordinate::getB()
{
return m_iY;
}
Line.h
#include<iostream>
#include<string>
#include"Coordinate.h"
class Line
{
public:
Line(int x1,int y1,int x2,int y2);
~Line();
void setA(int x,int y);
void setB(int x,int y);
void print();
private:
Coordinate m_coorA;
Coordinate m_coorB;
};
Line.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Line.h"
Line::Line(int x1, int y1, int x2, int y2) :m_coorA(x1, y1), m_coorB(x2,y2)
{
cout << "Line()" << endl;
}
Line::~Line()
{
cout << "~Line()" << endl;
}
void Line::setA(int x, int y)
{
m_coorA.setA(x);
m_coorB.setB(y);
}
void Line::setB(int x, int y)
{
m_coorA.setA(x);
m_coorB.setB(y);
}
void Line::print()
{
cout << "("<<m_coorA.getA()<<","<<m_coorA.getB()<<")"<< endl;
cout << "(" << m_coorB.getA() << "," << m_coorB.getB() << ")" << endl;
}
单元巩固:定义具有2个对象的Coordinate数组,遍历对象数组,打印对象信息(1,2),(3,4)
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
class coordinate
{
public:
coordinate()
{};
~coordinate()
{};
void print()
{
cout << "(" << m_iX << "," << m_iY <<")"<< endl;
}
public:
int m_iX;
int m_iY;
};
int main()
{
coordinate coorarr[4];
coorarr[0].m_iX = 1;
coorarr[0].m_iY = 2;
coorarr[1].m_iX = 3;
coorarr[1].m_iY = 4;
for (int i = 0; i < 2; i++)
{
coorarr[i].print();
}
system("pause");
return 0;
}
3.9 深拷贝和浅拷贝
对象拷贝是不是简单地做值得拷贝,而是将堆中内存的数据也进行拷贝叫深拷贝。简单的值拷贝是浅拷贝。
C++浅拷贝实践:
/*示例安排:
1.定义一个Array类,数据成员为m_iCount,成员函数包括数据封装函数,
构造函数,析构函数,拷贝构造函数,通过实践体会浅拷贝原理
2.增加数据成员m_pArr,并增加m_pArr地址查看函数,同时改造构造函数
析构函数,拷贝构造函数,通过实践体会深拷贝原理和必要性 */
#include<iostream>
#include<string>
#include<stdlib.h>
#include"Array.h"
using namespace std;
int main()
{
Array arr1;
arr1.setcount(5);
Array arr2(arr1);
cout << arr2.getcount() << endl;
system("pause");
return 0;
}
Array.h
#include<iostream>
class Array
{
public:
Array();
Array(const Array&arr);
~Array();
void setcount(int count);
int getcount();
private:
int m_iCount;
};
Array.cpp
#include<iostream>
#include"Array.h"
using namespace std;
Array::Array()
{
cout << "Array()" << endl;
}
Array::Array(const Array&arr)
{
m_iCount = arr.m_iCount;
cout << "Array(const Array&arr)" << endl;
}
Array::~Array()
{
cout << "~Array()" << endl;
}
void Array::setcount(int count)
{
m_iCount = count;
}
int Array::getcount()
{
return m_iCount;
}
C++深拷贝实践:
/*示例安排:
1.定义一个Array类,数据成员为m_iCount,成员函数包括数据封装函数,
构造函数,析构函数,拷贝构造函数,通过实践体会浅拷贝原理
2.增加数据成员m_pArr,并增加m_pArr地址查看函数,同时改造构造函数
析构函数,拷贝构造函数,通过实践体会深拷贝原理和必要性 */
#include<iostream>
#include<string>
#include<stdlib.h>
#include"Array.h"
using namespace std;
int main()
{
Array arr1(5);
Array arr2(arr1);
arr1.print();
arr2.print();
arr1.printarr();
arr2.printarr();
system("pause");
return 0;
}
Array.h
#include<iostream>
class Array
{
public:
Array(int count);
Array(const Array&arr);
~Array();
void setcount(int count);
int getcount();
void print();
void printarr();
private:
int m_iCount;
int *m_pArr;
};
Array.cpp
#include<iostream>
#include"Array.h"
using namespace std;
Array::Array(int count)
{
m_iCount = count;
m_pArr = new int[m_iCount];
for (int i = 0; i < m_iCount; i++)
{
m_pArr[i] = i;
}
cout << "Array()" << endl;
}
Array::Array(const Array&arr)
{
m_iCount = arr.m_iCount;
m_pArr = new int[m_iCount]; //先申请一段内存
for (int i = 0; i < m_iCount; i++) // 再将传入进来的对象对应位置的内存拷贝到申请的内存中去
{
m_pArr[i] = arr.m_pArr[i];
}
cout << "Array(const Array&arr)" << endl;
}
Array::~Array()
{
delete []m_pArr;
m_pArr = NULL;
cout << "~Array()" << endl;
}
void Array::setcount(int count)
{
m_iCount = count;
}
int Array::getcount()
{
return m_iCount;
}
void Array::print()
{
cout << "m_pArr的值是: " <<m_pArr << endl;
}
void Array::printarr()
{
for (int i = 0; i < m_iCount; i++)
{
cout << m_pArr[i] << endl;
}
}
3.10 对象指针
一个指针指向对象。
实例展示:
/*
1.定义一个Coordinate类
数据成员为m_iX ,m_iY
声明对象指针,并通过指针操控对象
计算两个点,横纵坐标的和 */
#include<iostream>
#include<stdlib.h>
#include"Coordinate.h"
using namespace std;
int main()
{
/*Coordinate *p1 = NULL;
p1 = new Coordinate;
Coordinate *p2 = new Coordinate();
p1->m_iX = 10;
p1->m_iY = 20; // 问题1的程序
(*p2).m_iX = 30;
(*p2).m_iY = 40;
cout << p1->m_iX + (*p2).m_iX << endl;
cout << p2->m_iY + (*p1).m_iY << endl;
delete[]p1;
p1 = NULL;
delete[]p2;
p2 = NULL;*/
Coordinate p1;
Coordinate *p2 = &p1;
p2->m_iX = 10; //问题2的程序
p2->m_iY = 20;
cout << p1.m_iX << " " << p1.m_iY << endl;
system("pause");
return 0;
}
Coordinate.h
#include<iostream>
using namespace std;
class Coordinate
{
public:
Coordinate();
~Coordinate();
public:
int m_iX;
int m_iY;
};
Coordinate.cpp
#include<iostream>
#include<stdlib.h>
#include"Coordinate.h"
using namespace std;
Coordinate::Coordinate()
{
cout << "Coordinate()" <<endl;
}
Coordinate::~Coordinate()
{
cout << "~Coordinate()"<< endl;
}
3.11 对象成员指针
/*
1.定义一个Coordinate类
数据成员为m_iX ,m_iY
成员函数:构造函数,析构函数,数据封装函数
线段类:Line
数据成员:点A指针 m_pCoorA,点B指针 m_pCooB
成员函数:构造函数,析构函数,信息打印函数 */
#include<iostream>
#include<stdlib.h>
#include"Line.h"
using namespace std;
int main()
{
Line *p = new Line(1, 2, 3, 4);
p->print();
cout << sizeof(p) << endl;
cout << sizeof(Line) << endl;
delete p;
p = NULL;
system("pause");
return 0;
}
Coordinate.h
#include<iostream>
using namespace std;
class Coordinate
{
public:
Coordinate(int x,int y);
~Coordinate();
int getX();
int getY();
private:
int m_iX;
int m_iY;
};
Coordinate.cpp
#include<iostream>
#include<stdlib.h>
#include"Coordinate.h"
using namespace std;
Coordinate::Coordinate(int x,int y)
{
m_iX = x;
m_iY = y;
cout << "Coordinate() " << m_iX<<","<<m_iY <<endl;
}
Coordinate::~Coordinate()
{
cout << "~Coordinate() " << m_iX << "," << m_iY << endl;
}
int Coordinate::getX()
{
return m_iX;
}
int Coordinate::getY()
{
return m_iY;
}
Line.h
#include<iostream>
#include<string>
#include"Coordinate.h"
class Line
{
public:
Line(int x1,int y1,int x2,int y2);
~Line();
void print();
private:
Coordinate *m_pCoorA;
Coordinate *m_pCoorB;
};
Line.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Line.h"
Line::Line(int x1, int y1, int x2, int y2)
{
m_pCoorA = new Coordinate(x1, y1);
m_pCoorB = new Coordinate(x2, y2);
cout << "Line()" << endl;
}
Line::~Line()
{
delete m_pCoorA;
m_pCoorA = NULL;
delete m_pCoorB;
m_pCoorB = NULL;
cout << "~Line()" << endl;
}
void Line::print()
{
cout << "print()" << endl;
cout << "("<<(*m_pCoorA).getX()<<","<<(*m_pCoorA).getY()<<")"<< endl;
cout << "(" << m_pCoorB->getX() << "," << m_pCoorB->getY() << ")" << endl;
}
3.12 this指针
指向对象自身数据的指针,当数据成员与参数同名时,可以使用this指针避免出错
*
示例要求:
定义一个Array类。
数据成员:m_Lien表示数组长度
成员函数:
构造函数,析构函数,len的封装函数,信息输出函数print */
#include<iostream>
#include<stdlib.h>
#include"Array.h"
using namespace std;
int main()
{
Array arr1(10);
arr1.print().setLen(5); // 用 Array& 加 return *this(或者Array* 加 return this)可以多个.连用
cout << "len= " << arr1.getLen() << endl;
system("pause");
return 0;
}
Array.h
#include<iostream>
class Array
{
public:
Array(int len);
//Array(const Array&arr);
~Array();
void setLen(int len);
int getLen();
Array& print();
private:
int len;
};
Array.cpp
#include<iostream>
#include"Array.h"
using namespace std;
Array::Array(int len)
{
this->len = len;
}
Array::~Array()
{
}
void Array::setLen(int len)
{
this->len = len;
}
int Array::getLen()
{
return len;
}
Array& Array::print()
{
cout << "len= " << len << endl;
return *this;
}