2011-04-19 28 views
32

我在C++函數中看到了一些內部結構的用法。在C++函數中使用本地類

有一個通用接口IBase。這是草稿的代碼。

class IBase 
{ 
    virtual Method()=0; 
} 

vector<IBase*> baseList; 

然後一個函數定義一個基於該IBase的內部類,然後將內部類對象推入到baseList中。

void func() 
{ 
    struct Object : public IBase 
    { 
     virtual Method() 
     { 
      // Method of Object in func 
     } 
    } 

    IBase* base = new Object(); 
    baseList->push(base); 

} 

這似乎是一個奇怪的用法,但是很好的實現了消息/事件創建模式。

其他線程可能會使用此baseList來處理傳入事件。

「struct Object」的內部結構的範圍是什麼?這很有趣。有一些文件在談論這個嗎?

回答

38

「struct Object」的內部結構的範圍是什麼?

本地類的範圍是它們被定義的函數。但這本身並不有趣。

是什麼使局部類有趣的是,如果他們實現一些接口(比如你的代碼做),那麼你就可以創建它的實例(使用new),並返回它們(例如,作爲std::vector<IBase*>),從而使通過基類指針實現可訪問即使在函數外面。

約局部類其他一些事實:

  • 他們不能定義靜態成員變量。

  • 它們不能訪問封閉函數的非靜態「自動」局部變量。但他們可以訪問static變量。

  • 它們可以在模板函數中使用。

  • 如果它們是在模板函數內部定義的,那麼它們可以使用封閉函數的模板參數。

  • 本地類是final的,這意味着函數外部的用戶不能從本地類派生到函數。如果沒有本地類,您必須在單獨的翻譯單元中添加一個未命名的名稱空間。

  • 本地類用於創建trampoline functions通常稱爲thunks


EDIT

從標準(2003)

9.8的一些參考文獻本地類聲明[class.local]

\ 1。一個類可以在一個函數定義中定義;這樣的班級是 ,稱爲本地班級。 本地類的名​​稱在其圍繞的 範圍內。本地類位於封閉示波器的 範圍內,並且具有對 函數以外的名稱的相同訪問權限,正如封裝的 函數一樣。本地 類中的聲明只能使用類型名稱,靜態變量 ,外部變量和 函數以及來自 的枚舉器。

[Example: 

int x; 
void f() 
{ 
    static int s ; 
    int x; 
    extern int g(); 

    struct local { 
     int g() { return x; } // error: x is auto 
     int h() { return s; } // OK 
     int k() { return ::x; } // OK 
     int l() { return g(); } // OK 
    }; 
// ... 
} 
local* p = 0; // error: local not in scope 

—end example] 

\ 2。封閉函數對本地類的成員沒有特殊訪問權限;它服從通常的訪問規則 (第11條)。 本地類的成員函數應在 的類定義內定義,如果它們全部定義爲 。

\ 3。如果類X爲嵌套類Y可以在 類X被聲明,後來在類X的 定義中所定義或稍後 在同一範圍爲類X的定義 一類內嵌套 定義的本地類本地班是本地班。

\ 4。本地類不得有靜態數據成員。

+0

*他們無法訪問非靜態局部變量。那意味着覆蓋虛擬函數不能訪問局部變量? – giggle 2011-04-19 10:11:29

+0

@giggle:不是直接的,但是你可以將它們作爲參數傳遞給構造函數,這樣'virtual'函數就可以使用它們。 – Nawaz 2011-04-19 10:14:12

+1

@giggle:只是澄清 - 覆蓋虛擬函數當然可以聲明和訪問它自己的本地變量。 Nawaz表示'func()'的局部變量。 – TonyK 2011-04-19 10:20:58

2

這是正常的C++。 範圍struct Object只是功能func。但是,仍然可以使用這種類型的對象,而不知道它們是哪個具體類型,因爲它們從IBase繼承。這用於封裝實現。

3

\ 4。本地類不得有靜態數據成員。

,但你可以做到這一點,局部類

int GetCount() 
{ 
    class _local 
    { 
    public: 
     static int Count(int count = std::numeric_limits<int>::max()) 
     { 
      static int count_ = 0; 
      if (count != std::numeric_limits<int>::max()) count_ = count; 
      return count_; 
     } 

     static float Operation(float a, float b) 
     { 
      _local::Count(_local::Count() + 1); 
      return a; 
     } 
    }; 
    _local::Count(0); 
    CALLBACK(_local::Operation); 
    return _local::Count(); 
} 

_local ::計數可用於讀取和寫入的內部否則靜態變量

-aydin

+0

這是使用方法來包圍值的非常有趣的方式。設置/獲取一種方法。 \t static int Count(int count = -1) { static int count_ = 0; if(count!= -1)count_ = count; return count_; } – aydin 2012-03-29 21:50:50