C++ using聲明和using指示


using 聲明

using聲明(using declaration),一次引入命名空間的一個成員。通過using聲明,我們可以清楚知道程序中使用的到底是哪個名字。using聲明不允許同名成員,如果有,就不能使用using聲明,可以用全名替代。
有效范圍從using聲明處開始,一直到using聲明所在的作用域結束為止,超出有效范圍就要使用全名,同時外層作用域的同名實體將被隱藏。
using聲明語句可以出現在global作用域、local作用域、namespace作用域以及class作用域。其中,在class作用域,using聲明只能指向基類成員(如using Base::size)。

形式:

using namespace_name::member_name

例如,如果不使用using聲明,聲明成員std::cout, std::endl,那么每次訪問時,就要帶上其命名空間(形如"std::"):

#include <iostream>

int main()
{
	std::cout << "hello, c++" << std::endl; // 沒有using聲明的成員,需要手動編寫完整名字
	return 0;
}

如果使用了using聲明,那么其作用域內,訪問對應成員時,無需"std::":

#include <iostream>

using std::cout;
using std::endl;

int main()
{
	cout << "hello, c++" << endl; // 已經添加了using聲明,作用域內,無需再編寫完整名字
	return 0;
}

using聲明與名稱遮掩

我們知道,在繼承體系中,derived class成員如果與base class成員同名,就會存在名稱遮掩問題(見Effective C++ 條款33),即通過derived class對象訪問成員時,無法訪問base的同名(重載)成員函數。而使用using聲明,可以消除這個問題。

存在名稱遮掩的示例

// 存在名稱遮掩問題
class Base {
public:
	void mf1();
	void mf1(int);
};

class Derived {
public:
	void mf1(); // 遮掩Base class的同名函數(包括Base的所有重載函數)
};

Derived d;
d.mf1(1); // 錯誤:由於Base::mf1名稱被Derived遮掩,無法訪問 void Base::mf1(int)

注:名稱遮掩與是否為virtual函數無關。

使用using聲明解決名稱遮掩問題:

// 不存在名稱遮掩問題
class Base {
public:
	void mf1();
	void mf1(int);
};

class Derived {
public:
	using Base::mf1; // Base的mf1在Derived可見,不再被遮掩
	void mf1();
};

Derived d;
d.mf1(1); // OK: 調用Base::mf1(1)

using 指示

using 指示(using directive)將namespace的所有成員提升到作用域可見。允許定義同名變量,如果要訪問global成員,就要使用"::i"這樣的符號。

namespace blip {
	int i = 16, j = 15, k = 23;
}

int j = 0;
int main()
{
	// using指示,blip中名字被“添加”到global作用域
	using namespace blip;

	++i;           // OK: blip::i 設為17
	++j;           // 二義性錯誤:是blip::j, 還是global j?
	++::j;         // OK: global j 設為1
	++blip::j;     // OK: blip::j設為16
	int k = 97;    // 當前局部k隱藏blip::k
	++k;           // OK: local k 設為98
	return 0;
}

頭文件與using聲明或者using指示

using聲明和using指示會將名字注入到所有包含該頭文件的文件中,而頭文件應該只負責定義接口部分的名字,而不定義實現部分的名字。因此,通常情況下,頭文件最多只在函數(local)作用域或namespace內使用using聲明或指示。

注意: 在頭文件中,盡量避免using指示,因為using指示會引入指定命名空間內所有成員名字,從而污染所有include該頭文件的文件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM