2012-02-15 95 views
0

這是內存映射文件共享的示例代碼。 mapped_region是負責它的d類 現在我深入挖掘之前,我不能跟蹤爲什麼使用這種聲明。任何人都可以向我解釋這個嗎?是否有可能有一個構造函數的參數作爲類名C++?

class mapped_region 
{ 
    // Non-copyable 
    mapped_region(const mapped_region &); 

    // Non-assignable 
    mapped_region &operator=(const mapped_region &); 

    public: 

    typedef /*implementation-defined*/ offset_t; 
    typedef /*implementation-defined*/ accessmode_t; 
    static const accessmode_t   invalid_mode; 
    static const accessmode_t   read_only; 
    static const accessmode_t   read_write; 
    static const accessmode_t   copy_on_write; 

    mapped_region(); 

    mapped_region(const memory_mappable & mappable 
       , accessmode_t   mode 
       , offset_t    mappable_offset 
       , std::size_t    size = 0 
       , const void *   address = 0); 

    mapped_region(mapped_region &&other); 

    std::size_t get_size() const; 

    void*  get_address() const; 

    offset_t get_offset() const; 

    accessmode_t get_mode() const; 

    void flush(std::size_t region_offset = 0, std::size_t numbytes = 0); 

    void swap(mapped_region &other); 

    ~mapped_region(); 
}; 

在這個例子中

// Non-copyable 
mapped_region(const mapped_region &); 

是什麼意思呢?

回答

3

是的,可以有一個參數名稱與class相同的構造函數。
兩種情況是可能的:

在您的代碼:

mapped_region(const mapped_region &); 

代表一個拷貝構造函數,而:

mapped_region(mapped_region &&other); 

代表移動構造函數

拷貝構造函數用於創建類對象的副本。無論何時您通過值傳遞類對象作爲函數參數或者需要您的類對象的副本,編譯器都會調用複製構造函數來創建此對象。

如果你想從使你的類對象的拷貝限制類的用戶,那麼你聲明複印功能拷貝構造函數 & 拷貝賦值運算符=)作爲private,這就是你的代碼在這種情況下,它會限制您的代碼的用戶創建您的類mapped_region的任何副本。請注意,一個類的默認訪問說明符是private

因爲你的代碼聲明瞭一個移動的構造,我假設你正在使用C++ 11,從而更好的方式在這裏實現所期望的功能是使用explicitly deleting special member functions在C++ 11提供。

對於如:

class mapped_region{ 
    mapped_region & operator=(const mapped_region&) = delete; 
    mapped_region(const mapped_region&) = delete; 
    mapped_region() = default; 
}; 
+0

非常感謝你,我現在可以更好地理解:) – Nisha 2012-02-15 11:41:09

+0

@judithnisha:沒問題。很高興能幫助你更好地理解:) – 2012-02-15 11:42:21

2

這是一個copy-constructor。它用於創建一個類的實例的副本。

mapped_region foo; 
mapped_region bar(foo); // creates bar as copy of foo 

如果聲明的拷貝構造函數是私有的,那麼在編譯器錯誤的第二行的結果,因爲它試圖訪問拷貝cosntructor。這樣做是爲了防止複製該類的對象。這通常在類包裝無法複製的資源(如文件或線程)時完成。

+0

是的,它說「不可複製」,因爲拷貝構造函數在這種情況下是私有的。 – 2012-02-15 10:55:38

+0

@LuchianGrigore:好的,做得更具體。 – 2012-02-15 10:57:17

+0

哦:)我現在明白了。 – 2012-02-15 10:58:31

2

class成員private默認。

class mapped_region 
{ 
    // Non-copyable 
    mapped_region(const mapped_region &); 

    // Non-assignable 
    mapped_region &operator=(const mapped_region &); 
public: 

    //... 
}; 

表示您聲明瞭複製構造函數和賦值運算符private。這意味着你不能相互拷貝類的對象。

1
mapped_region(const mapped_region &); 

是複製構造函數的聲明。

有時你不希望你的課是可複製的(所以你可以通過複製另一個來創建一個對象)。默認情況下,編譯器會創建複製構造函數並啓用複製。爲了防止編譯器創建此構造函數,您需要將其聲明爲私有,並省略其定義(實現)。試圖創建一個對象的副本會在這種情況下會失敗:

mapped_region mr1; 
mapped_region mr2(m1); // trying to call copy constructor call - error 

mapped_region mr1; 
mapped_region mr2 = m1; // trying to call copy constructor call - error 

註釋:

// Non-copyable 

應用於拷貝構造函數的私有聲明表明,它的目的僅僅是爲了防止編譯器創建一個默認的。 operator=也是如此。如果兩個成員都是私有的,則不能將一個對象複製或分配給另一個對象。

0

請注意,當您在該類的專用部分中定義一個複製構造函數時,則不會給它一個實現。

如果您嘗試複製該課程,您將得到一個鏈接錯誤。所以

void mapped_region::f() 
{ 
    mapped_region other(*this); // will compile because I have access to private functions 
} 

但代碼將不會鏈接,因爲它無法找到複製構造函數定義。 (請注意,如果你這樣做,可能很難找到你正在複製的地方)。

禁止複製的另一種方法是從升壓::不可複製派生類,即:

class mapped_region : boost::noncopyable 
{ 
    //etc. 

}; 

這樣可以防止拷貝賦值太(運算符=)。幾乎總是當你禁止複製時,你也禁止複製分配。