c++ 類作用域中的名字查詢
一.類成員宣告的名字查詢
按以下方式確定在類成員的宣告中用到的名字
什麼叫做類成員宣告的名字呢? 就是宣告一個函式用到的型別。 比如 doube max(x, y) 其實double 就是類成員宣告的名字。
* 先檢查出現在名字使用之前的類成員宣告,而這個之前是作用域內之前(1.全域性作用域的之前;2.區域性作用域的之前)
* 如果第一查詢不成功,則檢查包含類定義的作用域中出現的宣告以及出現在類定義之前的宣告.
例如:
typedef double Money;
class Account
{
public:
Money balance() { return bal;}
private:
Money bal;
};
在處理balance函式的宣告時,編譯器首先在類Account中查詢Money的宣告,編譯器只考慮出現在Moeny使用之前的宣告,因為找不到任何成員宣告,編譯器隨後在全域性作用域中查詢Money的宣告.找到了Money的宣告,並將它用作balance()函式的返回型別 和 資料成員bal的型別.
通常,名字必須在使用之前進行定義. 而且,如果一個名字被用作型別名, 該名字就不能重複定義:
typedef double Money;
class Account
{
public:
Money balance() { return bal;
}
typedef long double Money;
Money bal;
上面的程式碼回報錯,因為重複定義了Money.
二.在類成員定義中的名字查詢
類定義的名字查詢: 比如int pg; pg 就是類成員定義中的名字。
按以下方式確定在成員函式的函式體中用到的名字
* 首先檢測成員函式區域性作用域的宣告
*如果在成員函式中找不到該名字的宣告, 則檢查對所有類成員的宣告
*如果在類中找不到該名字的宣告,則檢查在此成員函式定義之前的作用域中出現的宣告
例如:
const int pg=10;
class A
{
public:
int fun(int pg)
{
return pg; //哪個pg?
}
private:
int pg;
};
上面的程式碼中fun()函式內return 的pg是哪個pg呢? 可以測試一下:
int main()
{
int x;
A test;
x=test.fun(3);
cout<<x<<endl;
return 0;
}
執行結果是三,說明函式fun()返回的是形參宣告的那個pg.
查詢fun的定義中使用的名字pg時, 編譯器首先在該函式的區域性作用域中查詢. 函式區域性作用域中宣告瞭一個函式形參.查詢成功, 形參pg會遮蔽名為pg的成員.
儘管類的成員被遮蔽了,仍然可以通過類名來限定成員名或顯示使用this指標來使用它.
int fun(double pg)
{
return this->pg;
//return A::pg;
}
函式作用域之後,在類作用域中查詢
如果想要使用pg成員, 更好的方式是為形參取一個不同的名字:
int fun ( int b)
{
return pg;
}
現在編譯器會在A類中查詢該名字,儘管pg是現在fun中使用,然後在宣告, 編譯器還是確定這裡用的是名為pg的資料成員. 所以用this指標和改變形參的名字都可以做到在類中查詢。
類作用域之後,在外圍作用域中查詢:
如果編譯器不能在函式或作用域中找到,就在外圍作用域中查詢.
上面的例子中, 在類A定義之前的全域性作用域中宣告瞭一個名為pg的全域性物件, 然後, 它被遮蔽了..
儘管全域性物件被遮蔽了,但通過全域性作用域確定操作符來限定名字,仍然可以使用它.
#include <iostream>
using namespace std;
const int pg=10;
class A
{
public:
int fun(double pg)
{
return ::pg; //這裡使用全域性作用域
}
A() : pg(0) { };
private:
double pg;
};
int main()
{
int x;
A test;
x=test.fun(3);
cout<<x<<endl;
return 0;
}
最後用課後習題總結一下:
解釋下述程式碼.指出每次使用Type或initVal時用到的是哪個名字定義.如果存在錯誤,說明如何改正.
typedef string Type;
Type initVal();
class Exercise
{
public:
typedef double Type;
Type setVal( Type);//類宣告的查詢,type 指的是 double; 類定義的查詢,這裡type 指的是還是double
Type initVal(); //這裡面類宣告的查詢type 也指的是double
private:
int val;
};
Type Exercise::setVal( Type parm) //;類宣告的查詢這裡type指的是string, 類定義的查詢 type指的是string,
{//為什麼是string呢? 因為它僅僅查詢函式只考慮它使用之前的宣告,而這個之前是不僅僅是位置上的之前,也是作用
域的之前,這個type屬於全域性作用域的之前。
val = parm + initVal(); //這裡initVal() 沒有函式體
}
Exercise::Type Exercise::setVal( Type parm)
{
val=parm + initVal();
retrun val;
}
注:形參表和函式體處於類作用域中,而函式返回型別不一定在類作用域中, 所以要在返回型別面前加上作用域運算子.
相關文章
- 7-3 名字查詢與類的作用域
- 名字查詢
- C++中一個名字查詢的小知識C++
- C和C++中的名字空間和作用域C++
- c++中的查詢list元素C++
- javascript 函式作用域中的關鍵字this的指向JavaScript函式
- 二分查詢(c++)C++
- 折半查詢(C++實現)C++
- ElasticSearch類似Mysql的not in 和 in 查詢ElasticsearchMySql
- C++ 逆向之 main 函式的查詢C++AI函式
- ffmpeg命令分類查詢
- C++ 變數型別查詢C++變數型別
- IP查詢類API介面查詢,含各精度IP歸屬地查詢介面API
- 快遞物流查詢API有什麼作用?API
- Java--String類查詢方法Java
- MongoDB 如何支援類 SQL 查詢MongoDBSQL
- C++中::的作用C++
- c++字串查詢函式實現C++字串函式
- 海關資料查詢系統「查詢平臺分類」
- C++編譯錯誤的正確查詢方式C++編譯
- SQL查詢的:子查詢和多表查詢SQL
- Mybatis騷操作-通用查詢工具類MyBatis
- 天氣出行、手機號查詢、簡訊、IP查詢類好用的介面推薦
- 關於C++中物件與類的詳解及其作用詳解C++物件
- 全域性作用域中,用const和let宣告的變數去哪了?變數
- Query.js - 類SQL前端資料查詢類庫JSSQL前端
- 如何在 SOLIDWORKS Simulation 中查詢反作用力Solid
- group by,having查詢 ”每**“的查詢
- Find and Replace Pattern(C++查詢和替換模式)C++模式
- 遞迴樹形查詢所有分類遞迴
- java 分庫關聯查詢工具類Java
- 【實測】Python 和 C++ 下字串查詢的速度對比PythonC++字串
- 包裝類的作用
- c++ 獲取資料夾目錄名字C++
- C++ Qt開發:QHostInfo主機地址查詢元件C++QT元件
- SQL:查詢每個類別最新的5條記錄SQL
- 建立支援類別下拉選單的Oracle查詢表DMOracle
- SSH:hiberate實現資料的查詢(單查詢和全查詢)
- Elasticsearch中的Term查詢和全文查詢Elasticsearch