2010-06-29 65 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(); 
};