C++自学笔记(13)之const在类与对象中的应用

1.常对象成员和常对象成员函数

(1)常对象成员

在之前的构造函数与析构函数部分已讲过,类似下图定义的常对象成员(在初始化后无法赋其他值),在初始化时只能通过初始化列表在构造函数初始化
在这里插入图片描述

(2)常对象成员函数

const除了能应用于对象成员,也能应用于对象成员函数,如下图左半部分,但是在定义时如果按照右上图那样对数据成员进行赋值是错误的,而对普通成员函数赋值是正确的(如右下图)。
在这里插入图片描述
主要会出错的原因是因为常成员函数中不能改变数据成员的值。
在定义普通成员函数时,系统会给成员函数一个隐含的this指针,如左图
在定义常对象函数时,这个this指针就会变成常指针,通过常指针去修改数据成员的值肯定是错误的。
在这里插入图片描述
此外,注意在类中定义的两个同名对象函数成员,尽管其中一个是常对象成员函数,这两个也互为重载,一般不推荐这么用
在这里插入图片描述
在用对象调用成员函数时,左图调用的是普通成员函数,右图是常对象成员函数。右图主要是通过const Coordinate coordinate (3,5);定义了一个常对象,以调用常对象成员函数
在这里插入图片描述
注意这里只是为了区分两个重构函数而采用常对象,事实上常对象和普通对象都能够调用常成员函数以及普通成员函数。

(3)代码例子

在这里插入图片描述
这里的代码是在C++自学笔记(10)之对象成员与数组的基础之上改的,主要是体现const的应用
有两个类 CoordinateLine

Coordinate.h

#pragma once
class Coordinate
{
public:
  Coordinate(int x,int y);
  ~Coordinate();
  void setX(int x);
  //因为诸如int getX() const; 实际上为int getX(Coordinate *this) const;
  //而在后面Line中调用常对象成员coorA,对应的是常指针,因此用常成员函数的方式 变为int getX(const Coordinate *this) const;
  //这里因为setX函数等需要赋值,故只对getX和getY规定常成员函数
  int getX() const;    
  void setY(int y);
  int getY() const;
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(int x)
{
	m_ix = x;
}
int Coordinate::getX() const  //常对象成员函数
{
	return m_ix;
}

void Coordinate::setY(int y)
{
	m_iy = y;
}
int Coordinate::getY() const  ///常对象成员函数
{
	return m_iy;
}

Line.h

#pragma once
#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 printfo();
	void printfo() const;   //定义一下试试是否会有重构函数
private:
	const Coordinate m_coorA;   // 将对象成员变成常成员
	Coordinate m_coorB;   
};

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已经是常对象成员,不能更改,先注释掉
	//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::printfo()
{
	//这里getX和getY已经是常成员函数
	cout << "printfo()" << endl;
	cout << "(" << m_coorA.getX() << "," << m_coorA.getY() << ")" << endl;
	cout << "(" << m_coorB.getX() << "," << m_coorB.getY() << ")" << endl;
}
void  Line::printfo() const
{
	cout << "printfo() const" << endl;
	cout << "(" << m_coorA.getX() << "," << m_coorA.getY() << ")" << endl;
	cout << "(" << m_coorB.getX() << "," << m_coorB.getY() << ")" << endl;
}

⑤主程序中

#include <iostream>
#include<stdlib.h>
#include <string.h>
#include "Coordinate.h"
#include "Line.h"

using namespace std;

int main(void)
{
	Line line(1,2,3,4);    
	line.printfo();
	
	const Line line1(5, 6, 7, 8);  //定义常对象以调用常对象函数printfo
	line1.printfo();
	
	system("pause");
	return 0;
}

运行结果如下
在这里插入图片描述

可见对数据成员为对象定义常对象成员时,该对象下的成员函数也要变常对象成员函数。且同名的常对象成员函数与普通成员函数构成重构函数。

2.对象的常指针与常引用

左图为类Coordinate的定义,常指针和常引用的定义可见右图
在这里插入图片描述
常引用与常指针只有读权限,而getX是有读写权限的一个函数,因此右图中的两个语句是错误的。

此外,如下图 Coor *const pCoor=&coor1;这种情况pCoor是不可以再指向其他位置,但是指针本身指向的对象是可变的,可见 *const pCoor是个有读写权限的指针,只限它指向的对象可以读写
在这里插入图片描述
因此第一个语句pCoor->getY();和第三个pCoor->printInfo();是具有读写权限的指针指向读写功能的函数以及只读功能的函数(常对象成员函数)。而pCoor不能再指向其他地址,因而第二个是错误的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值