《C++ 封装篇(下) imooc》笔记

来源:互联网 发布:淘宝卖家拍摄技巧 编辑:程序博客网 时间:2024/06/15 17:01

在堆中实例化数组时,可能会出现的问题:

//此时p指向第三个元素for(int i=0;i<3;i++){    cout << p->m_iX << endl;    p--;}//遍历完数组之后,p不是指向第一个元素,而是指向了数组之外的地方,故在释放内存时:p++;    //要释放内存,必须保证p是指向内存的第一个元素delete []p;    //如果不加[],释放的只是数组第一个元素的内存p = NULL;

对象成员

class Line{public:    Line(int x, int y):coorA(x, y){}    //如果Coordinate的构造函数是默认参数的,不使用初始化列表coorA(x,y)也是可以的;//如果Coordinate的构造函数是需要参数,则Line类的构造函数必要要有初始化列表或提供相应值private:    Coordinate coorA;    //不是一个基本类型,而是一个类的对象};

对象成员指针

private:    Coordinate* m_pCoorA;    //不同于上面,这里是一个指针

浅拷贝与深拷贝

浅拷贝

class Array{public:    Array(){m_iCount=5;p_iArr=new int[m_iCount];}    Array(Array &arr){        m_iCount = arr.m_iCount;        p_iArr = arr.p_iArr;}private:    int m_iCount;    int* p_iArr;}int mian(){    Array arr1;    Array arr2=arr1;}//此时Arr1和Arr2指向同一块内存地址,当释放Arr1,Arr2时,同一块内存地址被释放两次,会引发系统崩溃。

深拷贝

class Array{public:    Array(){m_iCount=5;p_Arr=new int[m_iCount];}    Array(Array & arr){        m_iCount = arr.m_iCount;        p_Arr = new int[m_iCount];        for(int i=0;i<m_iCount;i++){            p_Arr[i] = Arr.p_Arr[i];}}      

指针对象

//Coordinate.hclass Coordinate{public:    int m_iX,m_iY;}//demo.cpp    Coordinate c1;    Coordinate *c2=&c1;    //c1是对象,c2是指针

this指针

//Array.cppArray Array::printInfo{    return *this;    //返回arr1这个实例,但只是一个临时变量,arr1.printInfo().setLen(3)不会改变arr1的值}//上述改为Array& Array::printInfo{    return *this;    //返回的是arr1的引用,故arr1.printInfo().setLen(3)会改变arr1的值。}Array arr2 = arr1.printInfo();arr2.setLen(5)    //会改变arr1的值
//将上述的引用操作改为指针操作//Array.cppArray* Array::printInfo{    return this;}//demo.cpparr1.printInfo()->setLen(5);Array* arr2 = arr1.printInfo();arr2->setLen(3);    //此时arr1的len也是3

const

常对象成员

//Line.hprivate:    const Coordinate m_CoorA;    //对象成员为Coordinate类,且用const修饰//用实例化列表来实例化Line中常对象成员时,Line.cpp文件如下Line::Line(int x1, int y1):m_CoorA(x1, y1){}

常成员函数
常成员函数不能修改数据成员的值。

Void Coordinate::ChangeX()    //具有隐藏参数,如下{    m_iX = 10;}Void Coordinate::Change(Coordinate *this){    this->m_iX = 10;    //在编译的时候,编译器自动加上this指针}

当使用const修饰,变成常成员函数时,行为如下

Void Coordinate::ChangeX() const{    m_iX = 10;}//编译时,实际为Void Coordinate::ChangeX(const Coordinate *this){    this->m_iX = 10;    //this指向的是一个不变的Coordinate实例,显然不能通过指针该改变其值}
//在Coordinate.h中,ChangeX()与ChangeX() const发生重载,调用规则如下const Coordinate coorA(3,5);coorA.ChangeX();    //调用的是ChangeX()constCoordinate coorB(3,5);coorB.ChangeX();    //调用的是ChangeX()

对象引用与对象指针

常对象指针调用常成员函数,不能调用普通成员函数;
普通对象能够调用普通成员函数,也能调用常成员函数;
常指针和常引用都只能调用常成员函数。

Coordinate &coor2 = coor1;    //对象引用Coordinate* pCoor = &coor1;    //对象指针const Coordinate &coor2 = coor1;    //对象的常引用const Coordinate* pCoor = &coor1;    //对象的常指针//const修饰的实例只有读权限,没有写权限,在coor2.getX()时会报错。
Coordinate* const pCoor = &coor1;//pCoor依然具有读写权限,只是指向不变pCoor->getX() ;   //正确,getX()要求pCoor()具有写权限pCoor = &coor2;    //显然错误pCoor->printInfo()    //正确