程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 詳解C++中的this指針與常對象

詳解C++中的this指針與常對象

編輯:關於C++

詳解C++中的this指針與常對象。本站提示廣大學習愛好者:(詳解C++中的this指針與常對象)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C++中的this指針與常對象正文


C++ this指針詳解
this 是C++中的一個症結字,也是一個常量指針,指向以後對象(詳細說是以後對象的首地址)。經由過程 this,可以拜訪以後對象的成員變量和成員函數。
所謂以後對象,就是正在應用的對象,例如關於stu.say();,stu 就是以後對象,體系正在拜訪 stu 的成員函數 say()。
假定 this 指向 stu 對象,那末上面的語句中,this 就和 pStu 的值雷同:

Student stu; //經由過程Student類來創立對象
Student *pStu = &stu;

[示例] 經由過程 this 來拜訪成員變量:

class Student{
private:
  char *name;
  int age;
  float score;
public:
  void setname(char *);
  void setage(int);
  void setscore(float);
};
void Student::setname(char *name){
  this->name = name;
}
void Student::setage(int age){
  this->age = age;
}
void Student::setscore(float score){
  this->score = score;
}

本例中,函數參數和成員變量重名是沒有成績的,由於經由過程 this 拜訪的是成員變量,而沒有 this 的變量是函數外部的部分變量。例如關於this->name = name;語句,賦值號右邊是類的成員變量,左邊是 setname 函數的部分變量,也就是參數。

上面是一個完全的例子:

#include <iostream>
using namespace std;
class Student{
private:
  char *name;
  int age;
  float score;
public:
  void setname(char *);
  void setage(int);
  void setscore(float);
  void say();
};
void Student::setname(char *name){
  this->name = name;
}
void Student::setage(int age){
  this->age = age;
}
void Student::setscore(float score){
  this->score = score;
}
void Student::say(){
  cout<<this->name<<"的年紀是 "<<this->age<<",成就是 "<<this->score<<endl;
}
int main(){
  Student stu1;
  stu1.setname("小明");
  stu1.setage(15);
  stu1.setscore(90.5f);
  stu1.say();
  
  Student stu2;
  stu2.setname("李磊");
  stu2.setage(16);
  stu2.setscore(80);
  stu2.say();
  return 0;
}

運轉成果:

小明的年紀是 15,成就是 90.5
李磊的年紀是 16,成就是 80

對象和通俗變量相似;每一個對象都占用若干字節的內存,用來保留成員變量的值,分歧對象占用的內存互不堆疊,所以操尴尬刁難象A不會影響對象B。

上例中,創立對象 stu1 時,this 指針就指向了 stu1 地點內存的首字節,它的值和 &stu1 是雷同的;創立對象 stu2 時,this 等於 &stu2;創立對象 stu3 時也一樣。

我們無妨來證實一下,給 Student 類添加一個成員函數,輸入 this 的值,以下所示:

void Student::printThis(){
  cout<<this<<endl;
}


然後在 main 函數中創立對象並挪用 printThis:

Student stu1, *pStu1 = &stu1;
stu1.printThis();
cout<<pStu1<<endl;
Student stu2, *pStu2 = &stu2;
stu2.printThis();
cout<<pStu2<<endl;

運轉成果:

0x28ff30
0x28ff30
0x28ff10
0x28ff10

可以發明,this 確切指向了以後對象的首地址,並且關於分歧的對象,this 的值也紛歧樣。

幾點留意:
this 是常量指針,它的值是不克不及被修正的,一切妄圖修正該指針的操作,如賦值、遞增、遞加等都是不許可的。
this 只能在成員函數外部應用,其他處所沒成心義,也長短法的。
只要當對象被創立後 this 才成心義,是以不克不及在 static 成員函數中應用,後續會講到。
this 究竟是甚麼

現實上,this 指針是作為函數的參數隱式傳遞的,它其實不湧現在參數列表中,挪用成員函數時,體系主動獲得以後對象的地址,賦值給 this,完成參數的傳遞,無需用戶干涉。

this 作為隱式參數,實質上是成員函數的部分變量,不占用對象的內存,只要在產生成員函數挪用時才會給 this 賦值,函數挪用停止後,this 被燒毀。

正由於 this 是參數,表現對象首地址,所以只能在函數外部應用,而且對象被實例化今後才成心義。

C++常對象及其成員
C++固然采用了很多有用的辦法(如設private掩護)以增長數據的平安性,然則有些數據卻常常是同享的,人們可以在分歧的場所經由過程分歧的門路拜訪統一個數據對象。有時在有意當中的誤操作會轉變有關數據的狀態,而這是人們所不願望湧現的。

既要使數據能在必定規模內同享,又要包管它不被隨意率性修正,這時候可使用const,即把有關的數據界說為常量。
常對象

在界說對象時指定對象為常對象。常對象必需要有初值,如:

  Time const t1(12,34,46); //t1是常對象


如許,在一切的場所中,對象t1中的一切成員的值都不克不及被修正。凡願望包管數據成員不被轉變的對象,可以聲明為常對象。

界說常對象的普通情勢為:

  類名 const 對象名[(實參表列)];


也能夠把const寫在最左面:

  const 類名 對象名[(實參表列)];

兩者等價。

假如一個對象被聲明為常對象,則不克不及挪用該對象的非const型的成員函數(除由體系主動挪用的隱式的結構函數和析構函數)。例如,關於例9.7中已界說的Time類,假如有

  const Time t1(10,15,36); //界說常對象t1
  t1.get_time( ); //妄圖挪用常對象t1中的非const型成員函數,不法


這是為了避免這些函數會修正常對象中數據成員的值。

不克不及僅依附編程者的仔細來包管法式不失足,編譯體系充足斟酌到能夠湧現的情形,對不平安的身分予以攔阻。如今,編譯體系只檢討函數的聲明,只需發明挪用了常對象的成員函數,並且該函數未被聲明為const,就報錯,提請編程者留意。

援用常對象中的數據成員很簡略,只需將該成員函數聲明為const便可。如:

  void get_time( ) const ; //將函數聲明為const


這表現get_time是一個const型函數,即常成員函數。

常成員函數可以拜訪常對象中的數據成員,但依然不許可修正常對象中數據成員的值。有時在編程時有請求,必定要修正常對象中的某個數據成員的值,ANSI C++斟酌到現實編程時的須要,對此作了特別的處置,對該數據成員聲明為mutable,如:

  mutable int count;


把count聲明為可變的數據成員,如許便可以用聲明為const的成員函數來修正它的值。
常對象成員

可以將對象的成員聲明為const,包含常數據成員和常成員函數。

1) 常數據成員
其感化和用法與普通常變量類似,用症結字const來聲明常數據成員。常數據成員的值是不克不及轉變的。

有一點要留意: 只能經由過程結構函數的參數初始化表對常數據成員停止初始化。如在類體中界說了常數據成員hour:

  const int hour; //聲明hour為常數據成員

不克不及采取在結構函數中對常數據成員賦初值的辦法,上面的做法長短法的:

  Time::Time(int h){
    hour=h;
  } // 不法


由於常數據成員是不克不及被賦值的。

在類外界說結構函數,應寫成以下情勢:

  Time::Time(int h):hour(h){} //經由過程參數初始化表對常數據成員hour初始化


常對象的數據成員都是常數據成員,是以常對象的結構函數只能用參數初始化表對常數據成員停止初始化。


2) 常成員函數
後面已提到,普通的成員函數可以援用本類中的非const數據成員,也能夠修正它們。假如將成員函數聲明為常成員函數,則只能援用本類中的數據成員,而不克不及修正它們,例如只用於輸入數據等。如

  void get_time( ) const ; //留意const的地位在函數名和括號以後


const是函數類型的一部門,在聲明函數和界說函數時都要有const症結字,在挪用時不用加const。常成員函數可以援用const數據成員,也能夠援用非const的數據成員。const數據成員可以被const成員函數援用,也能夠被非const的成員函數援用。詳細情形可以用下表表現。

那末如何應用常成員函數呢?
假如在一個類中,有些數據成員的值許可轉變,另外一些數據成員的值不許可轉變,則可以將一部門數據成員聲明為const,以包管其值不被轉變,可以用非const的成員函數援用這些數據成員的值,並修正非const數據成員的值。
假如請求一切的數據成員的值都不許可轉變,則可以將一切的數據成員聲明為const,或將對象聲明為const(常對象),然後用const成員函數援用數據成員,如許起到“雙保險”的感化,實在包管
假如已界說了一個常對象,只能挪用個中的const成員函數,而不克不及挪用非const成員函數(豈論這些函數能否會修正對象中的數據)。這是為了包管數據的平安。假如須要拜訪對象中的數據成員,可將常對象中一切成員函數都聲明為const成員函數,但應確保在函數中不修正對象中的數據成員。

不要誤以為常對象中的成員函數都是常成員函數。常對象只包管其數據成員是常數據成員,其值不被修正。假如在常對象中的成員函數未加const聲明,編譯體系把它作為非const成員函數處置。

還有一點要指出,常成員函數不克不及挪用另外一個非const成員函數。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved