5-1 常对象成员和常成员函数
常成员函数:如果一个成员函数对类中数据成员只作访问而不作直接或间接的修改,则最好将此函数设置为常成员函数,以明确表示它对数据成员的保护性。
常对象:必须进行初始化,常对象只能调用常成员函数。
例子:
常对象成员:
常成员函数:
上图:常成员函数中为什么不能改变数据成员的值?
上图:编译后this指针是用const指针修饰的,成了一个常指针,通过常指针改变指针指向的数据是不被允许的;
上图中:互为重载,但不推荐这样使用;
上图:调用的是不带const的函数;
5-2 常对象成员和常成员函数实践
Coordinate.h
#include<iostream>
using namespace std;
class Coordiante
{
public:
Coordiante(int x,int y);
~Coordiante();
void setX(int _x);//第一个参数(this指针)不加也行(默认的),之所以报错的原因是m_coora只读,而this指针可读可写
void setY(int _y);
int getX() const;//m_coora只读,而this指针可读可写,所以加const修饰就只读了
int getY() const;//const修饰之后成为常成员函数;set函数不能加const
private:
int m_iX;//只有类里的成员函数才能访问private的成员?
int m_iY;
};
Coordinate.cpp
#include<iostream>
#include "Coordinate.h"
using namespace std;
Coordiante::Coordiante(int x,int y):m_iX(x),m_iY(y)//可以用初始化列表也可以不用;
{
//m_iX=x;
//m_iY=y;
cout<<"Coordiante()"<<m_iX<<","<<m_iY<<endl;
}
Coordiante::~Coordiante()
{
cout<<"~Coordiante()"<<m_iX<<","<<m_iY<<endl;
}
void Coordiante::setX(int _x)
{
m_iX = _x;
}
int Coordiante::getX() const
{
return m_iX;
}
void Coordiante::setY(int _y)
{
m_iY = _y;
}
int Coordiante::getY() const
{
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 printInfo();
void printInfo() const;
private:
const Coordiante m_coorA;//等价于Coordiante const m_coorA;
Coordiante m_coorB;
};
Line.cpp
#include "Line.h"
#include<iostream>
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<<"printInfo()"<<endl;
cout<<m_coorA.getX()<<","<<m_coorA.getY()<<endl;
cout<<m_coorB.getX()<<","<<m_coorB.getY()<<endl;
}
void Line::printInfo() const
{
cout<<"printInfo()const"<<endl;
cout<<m_coorA.getX()<<","<<m_coorA.getY()<<endl;
cout<<m_coorB.getX()<<","<<m_coorB.getY()<<endl;
}
demo.cpp
#include<iostream>
#include<stdlib.h>
//#include "Coordinate.h"//如果加了会出错:“class”类型重定义,只加line.h就行了(line.h已经引用了Coordinate.h)
#include "Line.h"
using namespace std;
int main(void)
{
Line l1(1,2,3,4);
l1.printInfo();
const Line l2(5,6,7,8);
l2.printInfo();
system("pause");
return 0;
}
运行结果
Coordiante()1,2
Coordiante()3,4
Line()
printInfo()
1,2
3,4
Coordiante()5,6
Coordiante()7,8
Line()
printInfo()const
5,6
7,8
请按任意键继续. . .
5-4 常指针与常引用
例子:
上图:常引用和常指针只有读权限,而getx()里的参数this是读写权限的,所以会出现错误,只能访问同样是常成员函数的printInfo;
上图:const在中间,指针不能指向其他对象,但指针指向对象的内容能变;说明此时是读写权限的指针,指向的对象可以读写,但不能指向其他位置;
pCoor->printInfo();指针是可读可写的,函数是可读的,所以可以(?)
5-5 练习题
普通对象可以调用常对象成员函数,常对象只能调用常成员函数;
5-6 单元巩固
定义一个坐标类,在栈上实例化坐标类常对象,并给出坐标(3,5),然后定义常引用、常指针,最后使用对象、引用、指针分别通过调用信息打印函数打印坐标信息。
#include <iostream>
using namespace std;
class Coordinate
{
public:
Coordinate(int x, int y)
{
// 设置X,Y的坐标
m_iX=x;
m_iY=y;
}
// 实现常成员函数
void printInfo() const
{
cout<<"("<<m_iX<<","<<m_iY<<")"<<endl;
}
public:
int m_iX;
int m_iY;
};
int main(void)
{
const Coordinate coor(3, 5);
// 创建常指针p
const Coordinate *p= &coor;
// 创建常引用c
const Coordinate &c=coor;
coor.printInfo();
p->printInfo();
c.printInfo();
return 0;
}
运行结果
(3,5)
(3,5)
(3,5)