C++(第三章——封装下)

在这里插入图片描述
" 天空很美、是吧?"

这篇文章将带我们了解到(以后内容将头文件省略):

  1. C++的对象成员
  2. C++的对象数组
  3. C++的深拷贝和浅拷贝
  4. C++的对象指针和对象指针成员
  5. C++的this指针
  6. C++的const + 对象、函数、对象成员

1、对象成员与对象数组

1.1、C++对象数组

  1. 从栈中
  • 从栈中开辟对象数组 Coordinate coord[3]
  • 对对象里面的数据成员赋值 coord[1].m_iX = 10(第二个对象)
  1. 从堆中
  • 从堆中开辟对象数组 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++对象数组实践

  1. 文件 “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;
}
  1. 文件 “Coordinate.h”
clss Coordinate
{
public:
  int m_iX;
  int m_iY;
  Coordinate();
  ~Coordinate();
};
  1. 文件 “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 分别赋值
  1. 文件 “demo.cpp”
int main(void)
{
  Line *p = new Line(1,2,3,4);
  delete p;
  p = NULL;
  system("pause");
  return 0;
}
  1. 文件 “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;
};
  1. 文件 “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;
}



  1. 文件 “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++对象成员指针

  1. 文件 “demo.cpp”
int main(void)
{
  Line *p = new Line(1,2,3,4);
  p->printInfo();
  delete p;
  p = NULL;
  system("pause");
  return 0;
}
  1. 文件 “Coordinate.h”
class Coordinate
{
public:
  Coordinate(int x,int y);
  ~Coordinate();
  int getX();
  int getY();
private:
  int m_iX;
  int m_iY;
};
  1. 文件 “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;
}
  1. 文件 “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;
} 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是我来晚了!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值