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++
- 查詢使用者轉儲檔案的名字及位置
- 各類查詢
- python變數作用域中容易忽略的點Python變數
- javascript 函式作用域中的關鍵字this的指向JavaScript函式
- 一個不錯的資料倉儲名字查詢網站網站
- c++中的查詢list元素C++
- iOS 快速更改類的名字iOS
- 失效的詞法作用域查詢規則?
- 折半查詢(C++實現)C++
- 二分查詢(c++)C++
- ElasticSearch類似Mysql的not in 和 in 查詢ElasticsearchMySql
- ffmpeg命令分類查詢
- 【Oracle】如何查詢並行是否起作用?Oracle並行
- 轉:C++實現的變種二分查詢法(折半查詢)--二叉查詢樹C++
- IP查詢類API介面查詢,含各精度IP歸屬地查詢介面API
- 海關資料查詢系統「查詢平臺分類」
- C++ 變數型別查詢C++變數型別
- 求教。。產品分類表的查詢
- 快遞物流查詢API有什麼作用?API
- 淘寶商品類目查詢方法怎樣檢視別人商品的類目淘寶類目查詢工具軟體
- C++中::的作用C++
- MongoDB 如何支援類 SQL 查詢MongoDBSQL
- C# LINQ查詢 類C#
- 靜態方法查詢類名
- C++ 查詢某個變數的型別C++變數型別
- 二叉查詢樹的實現——C++C++
- 資料結構與演算法——二叉查詢樹類的C++實現資料結構演算法C++
- c++字串查詢函式實現C++字串函式
- 關於C++中物件與類的詳解及其作用詳解C++物件
- SQL查詢的:子查詢和多表查詢SQL
- 天氣出行、手機號查詢、簡訊、IP查詢類好用的介面推薦
- Mybatis封裝分頁查詢的java公用類MyBatis封裝Java