2011-04-14 55 views
22

(在C++中)我有一個類,其結構在頭文件中聲明。該頭文件包含在很多源文件中,這樣當我編輯它時,我需要重新編譯大量文件。避免在類頭文件中聲明私有函數(C++)

該類有一組專用函數,它們只在一個源文件中被調用。目前它們在頭文件中的類結構中聲明。當我添加這種類型的新函數或編輯參數時,它會導致重新編譯大量文件。我想在其他地方聲明函數,以便只重定義並調用它們的文件(以節省時間)。不過,它們仍然需要能夠訪問內部類變量。

我該如何做到這一點?

+0

如果我從頭開始編寫這個類,有些方法可以很好地工作。但是,我並非從頭開始,這個班已經寫好了。 – user664303 2011-04-16 09:11:55

回答

4

無法在主類聲明之外聲明類的成員函數。所以,如果你想在所討論的類之外聲明可以訪問該類的特定實例的成員變量的函數,那麼我除了將該實例傳遞給該函數外,別無選擇。此外,如果你希望函數能夠訪問私有和受保護的變量,你將需要把它們放在一個新的類中,並使原來的類成爲它的朋友。例如。

header.h:

class FooImpl; 

class Foo { 
public: 
    int bar(); 
    friend class FooImpl; 
private: 
    int var; 
} 

impl.cpp:

#include "header.h" 

class FooImpl { 
public: 
    int bar(Foo &); 
} 

int FooImpl::bar(Foo &foo) { 
return foo.var; 
} 

int Foo::bar() { 
return FooImpl::bar(*this); 
} 
+0

這是我迄今爲止的理解,但我不是100%確定的。感謝收到的評論。 – user664303 2011-04-16 09:39:00

+0

你在'class Foo'中仍然有'int var'。問題的整個目的是將它移到'class FooImpl'? – balki 2013-03-06 13:04:58

+1

@balki:不,這個問題的關鍵在於如何在不改變標題的情況下在課堂中添加或編輯私人_函數_。如果我將私有變量移動到FooImpl,那麼我還必須將所有現有的公共函數轉發給該類。看到我對Erik關於這個問題的答案的第一個評論。 – user664303 2013-03-07 10:51:48

14

使用pImpl idiom - 您的可見類保留一個指向實際類,並將呼叫轉發給公共成員函數。

編輯:在迴應評論

// Foo.h: 

class FooImpl; // Do *not* include FooImpl.h 
class Foo { 
public: 
    Foo(); 
    ~Foo(); 
    //.. also need copy ctor and op= 
    int bar(); 
private: 
    FooImpl * Impl; 
}; 

// FooImpl.h: 

class FooImpl { 
public: 
    int bar() { return Bar; } 
private: 
    int Bar; 
}; 

// Foo.cpp: 

#include "FooImpl.h" 

Foo::Foo() { Impl = new FooImpl(); } 
Foo::~Foo() { delete Impl; } 
int Foo::bar() { return Impl->bar(); } 

保持實際執行你的FooImpl類 - Foo應該有FooImpl公衆成員的副本和簡單的轉發調用這些。所有用戶將只包含「Foo.h」 - 您可以更改FooImpl的所有私人詳細信息,而Foo的用戶看不到任何更改。

+0

謝謝。一般而言,這是個好主意。然而,在這種情況下,我並沒有開始使用這個框架,所以轉向它需要對我的類進行大量的重寫,包括爲它的所有公共函數編寫包裝。我希望能夠將標題中的一部分私有函數發送出去,沒有太多麻煩。 – user664303 2011-04-14 15:32:53

+0

@ user664303:繼承*可能是一個解決方案 - 這個特殊的問題是C++ imo令人討厭的謬誤之一。 – Erik 2011-04-14 15:37:50

+0

我是否認爲它必然需要類實例指針的轉換,例如:((priv_class *)this) - > priv_func();.或者有什麼辦法可以避免這種情況? – user664303 2011-04-14 16:13:15

1

創建一個抽象基類僅包含公共職能,並在你的標題參考這一點。創建你的真實課程作爲其他地方的實施。只有需要創建類的源文件需要查看實現類頭。