-----------------siwuxie095
常對象成員 和 常成員函數
看如下實例:
定義一個坐標類:Coordinate
要想正確的初始化,必須通過初始化列表來初始化,因為兩個數據成員
都是由 const 來修飾的,是常數據成員
作為一個類的數據成員來說,是可以用 const 來修飾的
顯然,對象作為數據成員,也是可以用 const 來修飾的,稱之為 常對象成員
以線段為例:當線段的位置一旦確定,就不能再更改
定義一個線段類:
因為要實現兩個點一旦初始化,就不能再修改,需要定義成 const
在構造函數中通過初始化列表來初始化:
在使用時:
const 不僅可以修飾數據成員,還可以修飾成員函數
const 修飾的成員函數,稱之為 常成員函數
「常成員函數中,const 修飾的實際上就是 this 指針」
看如下實例:
定義 changeX() 函數:上面的寫法是錯誤的,下面的寫法是正確的
常成員函數中為什么不能修改數據成員的值呢?
當定義 changeX() 函數時,看上去沒有任何的參數,而實際上
卻隱含着一個參數:this 指針
當成員函數不是一個普通的成員函數,而是一個 const 修飾過的
常成員函數時,依然有一個隱含的參數:this 指針,但 this 指針
是用 const 來修飾的,是一個常指針。通過常指針去改變該指針
指向的數據,肯定是不被允許的
所以,如果在常成員函數中去修改數據成員的值,這種做法就一定是錯誤的
此外,changeX() 和 changeX() const 二者互為重載
雖然從語法的角度來說,這個的確可以有,但如果真要去這么定義的話,
那我還是挺佩服你的,就像佩服孔乙己知道 回 字有 4 種寫法一樣
因為這樣定義,接下來在使用時,肯定會感到疑惑:調用的是哪個成員
函數?實際上調用的是不帶 const 的普通的成員函數 changeX()
那么在什么情況下可以調用常成員函數?
在實例化對象時,必須用 const 來修飾這個對象,這樣實例化的
對象,稱之為 常對象
通過常對象調用的 changeX(),就是用 const 修飾的常成員函數
程序:
Coordinate.h:
class Coordinate { public: Coordinate(int x,int y); ~Coordinate(); void setX(int x); //const修飾后只具有只讀權限所以可以修飾get函數 //相當於 int getX(const Coordinate *this); int getX() const; //而set函數具有寫權限所以不能用const(不能修改函數里面的值)修飾 void setY(int y); int getY() const; private: int m_iX; int m_iY; }; |
Coordinate.cpp:
#include "Coordinate.h" #include <iostream> 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:
#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); //常成員函數注意:const和括號之間要隔開一個空格不然有些編譯器下可能無法通過 //相當於 void printInfo(const Coordinate *this); //也就是說常成員函數的const實際上修飾的是this指針使之成為常this指針 void printInfo() const; // void printInfo(Coordinate *this); 隱藏的this指針 //同名的普通成員函數和常成員函數互為重載 void printInfo();
private: const Coordinate m_coorA;//一個常對象成員 Coordinate 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(int x); 相當於 setX(Coordinate *this,int x); //傳進去的是m_coorA的常this指針(只讀)m_coorA是個只具有讀權限的對象 //而原函數里的this既有讀權限又有寫權限 // //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() const { cout << "printInfo() const" << endl; cout << "(" << m_coorA.getX() << "," << m_coorA.getY() << ")" << endl; cout << "(" << m_coorB.getX() << "," << m_coorB.getY() << ")" << endl; }
void Line::printInfo() { cout << "printInfo()" << endl; cout << "(" << m_coorA.getX() << "," << m_coorA.getY() << ")" << endl; cout << "(" << m_coorB.getX() << "," << m_coorB.getY() << ")" << endl; } |
main.cpp:
#include <stdlib.h> #include "Line.h" using namespace std;
int main(void) { Line line1(1, 2, 3, 4); line1.printInfo();//調用的是不帶const的printInfo() const Line line2(5, 6, 7, 8); line2.printInfo();//調用的是帶const的printInfo() system("pause"); return 0; }
//即常對象和常對象成員只能調用常成員函數 //而普通的對象和對象成員卻可以調用普通成員函數和常成員函數 // //常數據成員和常對象成員必須使用初始化列表初始化 //(即const修飾的數據成員和對象成員在構造函數中只能用初始化列表初始化) //同名的普通成員函數和常成員函數互為重載 |
運行一覽:
【made by siwuxie095】