ZZ C 列舉型別的定義域問題

2021-05-21 22:06:50 字數 1525 閱讀 8650

c++ 中的列舉型別繼承於 c 語言。就像其他從 c 語言繼承過來的很多特性一樣,c++ 列舉也有缺點,這其中最顯著的莫過於作用域問題——在列舉型別中定義的常量,屬於定義列舉的作用域,而不屬於這個列舉型別。例如下面的示例:

enum fileaccess ;

fileaccess access = ::read; // 正確

fileaccess access = fileaccess::read; // 錯誤

c++列舉的這個特點對於習慣物件導向和作用域概念的人來說是不可接受的。首先,fileaccess::read 顯然更加符合程式設計師的直覺,因為上面的列舉定義理應等價於如下的定義(實際上,.net 中的列舉型別便是如此實現的):

class fileaccess ;

其次,這導致我們無法在同乙個作用域中定義兩個同樣名稱的列舉值。也就是說,以下的**是編譯錯誤:

enum fileaccess ;

enum fileshare ;

如果這一點沒有讓你惱怒過的話,你可能還沒寫過多少 c++ ** :-)。實際上,在最新的 c++0x 標準草案中有關於列舉作用域問題的提案,但最終的解決方案會是怎樣的就無法未卜先知了,畢竟對於象 c++ 這樣使用廣泛的語言來說,任何特性的增刪和修改都必須十分小心謹慎。

當然,我們可以使用一些迂迴的方法來解決這個問題(c++ 總是能給我們很多驚喜和意外)。例如,我們可以把列舉值放在乙個結構裡,並使用運算子過載來逼近列舉的特性:

struct fileaccess ;

__enum _value; // 列舉值

fileaccess(int value = 0) : _value((__enum)value) {}

fileaccess& operator=(int value)

operator int() const

}; 我們現在可以按照希望的方式使用這個列舉型別:

fileaccess access = fileaccess::read;

並且,因為我們提供了到 int 型別的轉換運算子,因此在需要 int 的地方都可以使用它,例如 switch 語句:

switch (access)

當然我們不願意每次都手工編寫這樣的結構。通過使用巨集,我們可以很容易做到這一點:

#define declare_enum(e) struct e e& operator=(int value) operator int() const enum __enum ; private: __enum _value; };

我們現在可以按如下的方式定義前面的列舉,並且不比直接寫 enum 複雜多少。

declare_enum(fileaccess)

read = 0x1,

write = 0x2,

end_enum()

declare_enum(fileshare)

read = 0x1,

write = 0x2,

end_enum()

還有一些列舉型可以盡量寫在某個類的定義內

對數函式定義域和值域為r 函式的定義域(高中)

函式的定義域是我們上了高中後接觸到的新的名詞,其實相關知識我們早有接觸,其實它就是我們之前學習函式中自變數x的取值範圍,到了高中我們將這個取值範圍定義為函式的定義域。那如何理解定義域呢?數學總是抽象難理解的,函式更上如此,所以相當一部分同學聽到函式就頭皮發麻。所以為了了解抽象的定義域我先從具體的事例...

geogebra中函式的定義域的輸入

ggb中函式的輸入有如下幾種方式 一 如果if做法 1 區間函式 做出函式在某區間上的圖象 f x if x 0 x 2,x 2 2x 1 2 分段函式 做出分段函式的圖象 f x if x 0 x 2,x 2 2x 1,if x 2 x 4,x 3 2x 1 3 逐點序列函式 逐點做出函式的影象 ...

ios OC中的類宣告 定義域等等概念

oc關鍵字定義為 class o c特有的語句for in 迭代迴圈,其他的條件和迴圈語句和c一樣 oc對物件導向的概述 1 基類 nsoject 2 一般的繼承是單繼承,使用協議 protocol 實現多重繼承 3 所有的函式都是虛函式 id型別 oc中每個目標都可以表達為id型別,泛型。可以認為...