C++ 數據共享與保護
1.作用域
作用域:一個標識符在程序正文中有效的區域。
函數原型(函數聲明)作用域
例如函數原型void Print(int a);
,變量a的作用域為括號左右之間。
局部作用域
例如如下函數定義,變量a
的作用域為大括號之間。
void Print(){ int a = 0; std::cout << a << std::endl; }
類作用域
X
類的成員m
具有類作用域(設其一個實例對象為x),以下是在不同環境下對m的訪問方法:
1.類內訪問:
直接通過標識符m訪問。
2.類外訪問:
普通成員通過x.m
類成員通過
X::m
對象指針通過
ptr->m
命名空間作用域
在XX命名空間中聲明的對象m,其作用域在命名空間之內。命名空間外想訪問該對象要以XX::m的方式進行。
namespace XX{ // 命名空間中聲明 void Print(); } XX::Print(){ // 命名空間外定義 //Print函數的定義 } XX::Print() // 命名空間外使用
using
語句可以簡化對命名空間內對象的訪問:
- 1.使用
using XX::Print
;語句後,其後隻需要通過Print就可以調用該函數對象。 - 2.使用
using namespace XX
;語句後,其後隻需要通過函數名就可以調用XX命名空間下的對象。
2.可見性
可見性:程序運行到某一點,能夠引用到的標識符,稱該標識符為可見的。
可見性隱藏規則:在多個具有包含關系的作用域聲明的同名標識符,外層標識符在內層不可見。
全局變量:可以被本程序所有對象或函數引用。
- 在默認(全局)命名空間內聲明的對象為全局變量,默認本編譯單元內可以引用。
- 通過關鍵詞
extern
聲明引用的全局變量為其他編譯單元中已經定義的全局變量。 - 通過關鍵詞
static
聲明的全局變量隻能在本編譯單元中使用,不能在其他編譯單元用extern
聲明引用。
局部變量:隻能在內部作用域內被引用
3.對象的生存期
生存期:從對象內存空間被分配到被釋放的期間。
靜態生存期:對象的生存期與程序的運行期相同。
- 1.在命名空間內聲明的對象都具有靜態生存期。
- 2.在局部作用域中用
static
關鍵詞聲明的對象具有靜態生存期,在對應局部作用域中具有可見性。
動態生存期:對象的生存期為聲明點到聲明點所在作用域的結束點之間。
4.類數據的共享
面向結構編程:
程序模塊:函數
數據共享方式:參數傳遞、全局變量
面向對象編程:
程序模塊:類
數據共享方式:類的靜態成員(類內數據共享)、類的友元(類外數據共享)
類的靜態數據成員(類屬性):類變量由該類所有實例對象共享,用static修飾。
設X類的靜態成員為m,類的一個實例對象為x:
- 類的靜態變量必須類內聲明,類外定義。
- 在類的第一個實例對象初始化前初始化,在內存上隻有一份副本。
- 類外定義時通過X::m進行引用,定義後可以通過實例對象進行引用,如x.m。
類的靜態函數成員(類方法):主要是處理類屬性或者處理該類下多個實例對象的方法,用static
修飾。
設X類的靜態函數為func,類的一個實例對象為x:
- 可以直接訪問該類的靜態數據和函數成員,不能訪問非靜態成員。
- 可以在類的第一個實例對象初始化前通過
X::func
進行調用。 - 在實例對象初始化可以通過
x.func
調用,但是為瞭代碼的可讀性,不推薦這樣使用。
// 靜態成員案例 #include<iostream> using namespace std; class A { public: static int s_count; // 私有靜態數據成員聲明 static void set_count(int i) { // 靜態方法定義 s_count = i; } void UsingCount(){ s_count++; } }; int A::s_count = 0; // 私有靜態數據成員類外定義(註意要在前面加上數據的類型說明符) int main() { A::s_count; // 通過類名調用 A::set_count(11); // 對象初始化前通過靜態函數成員訪問 A a1; a1.UsingCount(); // 通過普通函數成員修改靜態數據成員 cout << a1.s_count << endl; // 通過對象訪問靜態數據成員 A a2; a2.UsingCount(); cout << a2.s_count << endl; // 如果輸出結果是13,則證明靜態數據成員是共享的 }
輸出結果:
12
13
友元關系:一個類主動聲明其他類或函數是他的友元,進而給他們提供本類的訪問特許,用friend
修飾。
友元函數:被一個類聲明為友元的函數,在他的函數體內可以通過對象名訪問類的私有和保護成員。
友元類:被一個類A聲明為友元的另一個類B,類B內所有成員函數都是類A的友元函數。
//友元數據共享案例 #include<iostream> using namespace std; class A { private: int m_nums = 10; // 私有數據成員 friend class B; // 友元類聲明 }; class B { // 友元類 public: void Print(A& a) { // 友元函數 cout << a.m_nums << endl; // 通過對象名訪問私有成員 } }; int main() { A a; B b; b.Print(a); // 訪問私有數據成員 }
結果輸出:
10
1
5.類共享數據的保護
常對象:常對象的數據成員值在對象整個生存期間不能被更改。
設A類的常對象為a
,常函數成員為func
,常數據成員為m
:
- 1. 聲明語法:
const A a
; - 2. 常對象必須進行初始化,而且不能被更新(不能賦值或者調用普通成員函數)。
- 3. 常對象隻能調用常函數成員。
常函數成員:能被常對象調用訪問常數據成員。
- 1. 常函數成員聲明語法:返回值類型 func(參數表)const;
- 2. 常函數成員定義部分時要帶上
const
。 - 3. 常函數調用期間,因為目標對象視為常對象,所以隻能調用常函數。
- 4.
const
可以用於函數重載,通過非const
對象調用重載函數優先調用非const的重載函數。
常數據成員:值在初始化後不能被更新。
- 1. 常數據成員聲明語法:
const
數據類型m
;。 - 2. 常數據成員不能被賦值,構造函數隻能通過初始化列表進行初始化。
- 3. 靜態常數據成員在類外進行定義。
//常成員案例 #include<iostream> using namespace std; class A { public: void Print()const { // 不修改對象數據成員值的函數應該設為常函數 cout << a << ',' << b << ',' << s << endl; } A(int i) :b(i) {}; // 初始化列表初始化 private: const int a = 1; // 已初始化的常數據成員 const int b; // 未初始化的常數據成員 const static int s; // 常靜態數據成員 }; const int A::s = 3; // 類外定義 int main() { A a(2); a.Print(); }
結果輸出:
1,2,3
1
常引用:常引用所引用的對象被視為常對象。
- 1. 常引用聲明語法:
const
數據類型 &引用名。 - 2.非
const
的引用隻能綁定到普通對象。 - 3. 對於無需修改值的參數(復制構造函數),盡量使用
const
進行應用
到此這篇關於C++ 數據共享與保護的文章就介紹到這瞭,更多相關C++ 數據共享與保護內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 詳解C++ 共享數據保護機制
- C++內存模型與名稱空間概念講解
- C++深入淺出講解內存四區與new關鍵字的使用
- C++ 命名空間 using聲明使用示例詳解
- 一篇文章詳細解釋C++的友元(friend)