" 天空很美、是吧?"
C++(内容基于慕课网James _ yuan课程)
这篇文章将带我们了解到(以后内容将头文件省略):
- C++的对象成员
- C++的对象数组
- C++的深拷贝和浅拷贝
- C++的对象指针和对象指针成员
- C++的this指针
- C++的const + 对象、函数、对象成员
1、对象成员与对象数组
1.1、C++对象数组
- 从栈中
- 从栈中开辟对象数组 Coordinate coord[3]
- 对对象里面的数据成员赋值 coord[1].m_iX = 10(第二个对象)
- 从堆中
- 从堆中开辟对象数组 Coordinate *p = new Coordinate[3]
- 对对象里面的数据成员赋值 p[0].m_iY = 20 或 p->m_iY = 20(第一个对象)
- 注意需要手动销毁内存、并将内存置为空
clss Coordinate
{
public:
int m_iX;
int m_iY;
};
int main(void)
{
Coordinate coord[3];
coord[1].m_iX = 10;
Coordinate *p = new Coordinate[3];
p[0].m_iY = 20; p->m_iY = 20;
//p[1].m_iY = 10 和 (p+1)->m_iY = 10 意义一样
//是给第二个对象赋值
delete [ ]p;
p = NULL;
return 0;
}
1.2、C++对象数组实践
- 文件 “demo.cpp”
- 下列程序从栈和堆中分别开辟对象
- 无论是哪种方式 Coordinate coor[3] 和 Coordinate *p = new Coordinate[3] 都将调用构造函数
int main(void)
{
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++;
//p指向第二个对象
p->m_iX = 11;
p[0].m_iY = 13;
//p指向第二个对象
p[1].m_iX = 15;
//p指向第三个对象
P++;
P->m_iY = 17;
//p指向第三个对象
for(int i = 0;i < 3;i++)
{
cout<< "coor_x" << coor[i].m_iX <<endl;
cout<< "coor_y" << coor[i].m_iY <<endl;
}
//因为我们并没有给coor[1].m_iX、coor[2].m_iX和
//coor[1].m_iY、coor[2].m_iY赋值、所以打印出来的是乱码
for(int j = 0;j < 3;j++)
{
cout<< "p_x" << p[j].m_iX <<endl;
cout<< "p_x" << p[j].m_iX <<endl;
p--;
}
//p指向第零个对象
p++;
delete [ ]p;
//删除内存的时候、指针一定要指向开辟时的首地址
p = NULL;
system("pause");
return 0;
}
- 文件 “Coordinate.h”
clss Coordinate
{
public:
int m_iX;
int m_iY;
Coordinate();
~Coordinate();
};
- 文件 “Coordinate.cpp”
Coordinate::Coordinate()
{
cout<< "Coordinate" <<endl;
}
Coordinate::~Coordinate()
{
cout<< "~Coordinate" <<endl;
}
1.3、对象成员
对象成员:在对象中包含的其他对象被称为对象成员
定义一个线段的类、其中包含二个点、每个点作为类又包括横纵坐标
当我们在主函数里面开辟了一个内存为Line()的点 Line *p = new Line() 、系统会先调用坐标点A和B的构造函数、最后调用线段的构造函数、析构函数反过来调用
- 我们先观察第一个程序、实例化了一个对象(从堆中)、并且在实例化对象的时候传递了参数值
- 我们再观察第四个程序、也就是将 x1 = 1 、y1 = 2 、x2 = 3 、y2 = 4
- 我们再观察第五个程序、也就是用初始化列表的方式m_coorA(x1,y1) m_coorB(x2,y2)
- 我们再观察第二个程序、也就是 Coordinate(int x1,int y1) 和 Coordinate(int x2,int y2)
- 我们再观察第三个程序、也就是 将 m_iX 和 m_iY 分别赋值
- 文件 “demo.cpp”
int main(void)
{
Line *p = new Line(1,2,3,4);
delete p;
p = NULL;
system("pause");
return 0;
}
- 文件 “Coordinate.h”
class Coordinate
{
public:
Coordinate(int x,int y);
~Coordinate();
void setX(int x);
int getX();
void setY(int y);
int getY();
private:
int m_iX;
int m_iY;
};
- 文件 “Coordinate.cpp”
#include <iostream>
#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::setX(intx)
{
m_iX = x;
}
int Coordinate::getX()
{
return m_iX;
}
void Coordinate::setY(int y)
{
m_iY = y;
}
int Coordinate::getY()
{
return m_iY;
}
- 文件 “Line.h”
#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 printfInfo();
private:
Coordinate m_coorA;
Coordinate m_coorB;
};
5.文件 “Line.cpp”
#include <iostream>
#include "Line.h"
using namespace std;
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.setX(x);
m_coorA.setY(y);
}
void Line::setB(int x,int y)
{
m_coorB.setX(x);
m_coorB.setY(y);
}
void Line::printInfo()
{
cout<< "(" << m_coorA.getX() << "," << m_coorA.getY() << ")" <<endl;
cout<< "(" << m_coorB.getX() << "," << m_coorB.getY() << ")" <<endl;
}
2、深拷贝与浅拷贝
2.1、浅拷贝
class Array
{
public:
Array(){m_iCount = 5;m_pArr = new int[m_iCount];}
Array(const Array& arr)
{m_iCount = arr.m_iCount;
m_pArr = arr.m_pArr;}
//我们把 arr 看成 arr1、m_iCount 看成是 arr2 的数据成员、这样就可以完成值的简单传递
//同样的是我们也完成了指针地址的传递、但是这样做会导致 arr1 和 arr2 的数据成员指针指向相同的地址、显然是不正确的
private:
int m_iCount;
};
int main(void)
{
Array arr1;
Array arr2 = arr1;
return 0;
}
2.2、深拷贝
class Array
{
public:
Array(){m_iCount = 5;m_pArr = new int[m_iCount];}
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];}}
private:
int m_iCount;
int *m_pArr;
};
int main(void)
{
Array arr1;
Array arr2 = arr1;
return 0;
}
3、对象指针
3.1、C++对象指针
class Coordinate
{
public:
int m_iX;
int m_iY;
};
int main(void)
{
Coordinate *p = new Coordinate;
p->m_iX = 10;//(*p).m_iX = 10;
p->m_iY = 20;//(*p).m_iY = 20;
delete p;
p = NULL;
return 0;
};
3.2、C++对象成员指针
- 文件 “demo.cpp”
int main(void)
{
Line *p = new Line(1,2,3,4);
p->printInfo();
delete p;
p = NULL;
system("pause");
return 0;
}
- 文件 “Coordinate.h”
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 "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 "Coordinate.h"
class Line
{
public:
Line(int x1,int y1,int x2,int y2);
~Line();
void printfInfo();
private:
Coordinate *m_coorA;
Coordinate *m_coorB;
};
5.文件 “Line.cpp”
#include <iostream>
#include "Line.h"
using namespace std;
Line::Line(int x1,int y1,int x2,int y2):m_coorA(x1,y1),m_coorB(x2,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::setA(int x,int y)
{
m_coorA.setX(x);
m_coorA.setY(y);
}
void Line::setB(int x,int y)
{
m_coorB.setX(x);
m_coorB.setY(y);
}
void Line::printInfo()
{
cout<< "(" << m_coorA->getX() << "," << m_coorA->getY() << ")" <<endl;
cout<< "(" << m_coorB->getX() << "," << m_coorB->getY() << ")" <<endl;
}
3.3、this指针
class Array
{
public:
Array(int _len){len = _len;}
int getLen(){return len;}
void setLen(int _len){len = _len;}
private:
int len;
};
思考:如果参数与数据成员同名会怎么样?
class Array
{
public:
Array(int len){len = len;}
int getLen(){return len;}
void setLen(int len){len = len;}
private:
int len;
};
this指针表达是哪个地址、就能访问其对应的数据
* Array arr1 this指针就是&arr1
* Array arr2 this指针就是&arr2
class Array
{
public:
Array(int len){this->len = len;}
int getLen(){return len;}
void setLen(int len){this->len = len;}
private:
int len;
};
3.3、this指针实践
class Array
{
public:
Array(int len);
~Array();
Array& setLen(int len);// Array* setLen(int len);
int getLen();
Array& printInfo();//Array* printInfo();
private:
int len;
};
Array::Array(int len);
{
this->len = len;
}
Array::~Array();
{
}
Array& Array::setLen(int len);
{
this->len = len;
return *this//return this
}
int Array::getLen();
{
return m_iLen;
}
Array& Array::printInfo();
{
cout<< "len=" << len <<endl;
return *this;//return this
}
int main(void)
{
Array arr1(10);
cout<< arr1.getLen() <<endl;
arr1.printInfo().setLen(5).printInfo()
system("pause");
return 0;
}
4、const再现江湖
4.1、常对象成员(初始化列表赋值)
class Line
{
public:
Line(int x1,int y1,int x2,int y2);
~Line();
void printfInfo();
private:
const Coordinate m_coorA;
const Coordinate m_coorB;
};
4.2、常成员函数
class Coordinate
{
public:
Coordinate(int x,int y);
void changeX() const;
void changeX();
//互为重载
private:
int m_iX;
int m_iY;
};
在常成员函数下不能修改数据成员的值
* 错误
* void Coordinate::changeX() const
* {
* m_iX = 10;
* };
* 正确
* void Coordinate::changeX()
* {
* m_iX = 10;
* };
void Coordinate::changeX(Coordinate *this)
{
this->m_iX = 10;
};
void Coordinate::changeX(const Coordinate *this)
{
this->m_iX = 10;
};
调用被const修饰过的函数
int main(void)
{
const Coordinate coordinate(3,5);
//常对象
coordinate.changeX();
return 0;
}
4.3、常指针与常引用
class Coordinate
{
public:
Coordinate(int x,int y);
int getX() const;
int getY() const;
void printInfo() const;
private:
int m_iX;
int m_iY;
};
常指针和常引用只能调用常成员函数
int main(void)
{
Coordinate coor1(3,5);
const Coordinate &coor2 = coor1;
const Coordinate *pCoor = &coor1;
coor2.getX();
pcoor->getY();
return 0;
}