是否可以不在类头文件中包含类变量?

时间:2010-06-29 01:20:57

标签: c++

我想隐藏实现文件中的实现。如果对象不是公共的,我不希望对象的标题在我的类被使用的任何地方泄漏。

假设我的班级A.h有头文件A

#include "Foo.h"

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

现在无论我将A.h包括在内,Foo.h也会包括在内。但是我在课堂Foo之外的任何地方都没有使用课程A。我宁愿没有这条#include "Foo.h"行。有没有办法在实现A.cpp中移动'foo'变量的声明?

我怀疑一个可能的解决方案是添加一层抽象类(接口类比)。这是最好的解决方案吗?

谢谢。

3 个答案:

答案 0 :(得分:12)

使用指向Foo的指针并动态分配它,而不是使用成员对象。然后你只需要在A.cpp中包含Foo.h。

class Foo;

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

答案 1 :(得分:1)

大卫得到了正确的答案。我将参考这篇文章,对这种“不透明指针”技巧进行更多处理,因为根据您的需要,您可以更详细地了解它:

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

此外,为此目的使用shared_ptr类型而不是像示例那样的原始指针是个好主意。一旦最后一次引用Foo超出范围,这将自动为您清理资源。

答案 2 :(得分: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.i.e。中,从文档中省略它并命名它以吓跑窥探的眼睛:

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