2010-06-29 61 views
1

我想隱藏實現文件中的實現。如果對象不公開,我不希望對象的頭部在我的類被使用的任何地方泄漏。是否有可能不在類頭文件中包含類變量?

假設我有頭文件A.hA類:

現在,無論我將包括A.hFoo.h也將被包括在內。但我沒有用A類以外任何地方的Foo類。我寧願沒有這個#include "Foo.h"線。有沒有辦法在執行A.cpp的內部移動'foo'變量的聲明?

我懷疑一個可能的解決方案涉及添加一層抽象類(接口類比)。這是最好的解決方案嗎?

謝謝。

回答

12

使用指向Foo的指針並動態分配它,而不是使用成員對象。那麼你只需要在A.cpp中包含Foo.h。

class Foo; 

class A{ 
    private: 
     Foo* foo; 
    public: 
     do_stuff(); 
} 
+7

+1,這是「PIMPL」的習慣用法,並且是標準做法。 – greyfade 2010-06-29 01:30:49

+0

對答案+1,對greyfade +1,指出它基本上是一個pimpl(指向私有實現細節的不透明指針)。 – stinky472 2010-06-29 01:48:29

+0

不錯!謝謝。我記得看過這個成語,但當時我沒有注意它。 – Bear 2010-06-29 01:50:43

1

大衛的得到了正確的答案。我將把這個文章多一點的治療對這種「不透明指針」的把戲,因爲你可以得到更精細的,根據您的需要:

http://en.wikipedia.org/wiki/Opaque_pointer

而且,這是一個很好想法爲此目的使用shared_ptr類型,而不是像樣本這樣的原始指針。一旦最後一次引用Foo超出範圍,這將自動爲您清理資源。

+1

我是共享指針的粉絲,但我認爲它在這種情況下的矯枉過正。它通常在所有權複雜時使用。如果foo僅用於創建它的A對象,則不存在所有權問題。 – KeithB 2010-06-29 12:02:35

0

是的。選擇你的毒藥!

選項1.接口中的前向聲明。

class A { 
    private: 
     class Foo; 
     Foo* foo; 
}; 

選項2. ABC。

// A.hpp 
class A { 
    public: virtual void do_stuff() = 0; 
}; 

// A.cpp 
class A_impl : public A { 
    class Foo { /*etc*/ }; 
    Foo foo; 
    void do_stuff(){...} 
}; 

選項3.私人是私人的。這是「隱藏」至於公共API去,這是最重要的事情:

class A { 
    private: 
     class Foo { 
      ... 
     }; 
     private_::Foo foo; 
    public: 
     do_stuff(); 
}; 

選項4.只要將申報「非公開」 namespace.ie,從文件省略它,並將它命名有些東西嚇跑窺探的眼睛:

namespace private_ { 
    class Foo { 
     ... 
    }; 
} 
class A { 
    private: 
     private_::Foo foo; 
    public: 
     do_stuff(); 
};