私人/公共标题示例?

时间:2010-02-16 12:11:21

标签: c++ header private-header

有人可以举个例子说明公共和私人标题的工作原理吗?我已经在网上做了一些阅读,但我似乎找不到有关示例代码的有用信息。我被告知我应该使用私有标头来分隔我的代码的公共和私有部分,以创建静态库。经过一番阅读后,我对它是如何工作有了一个大概的了解,但我真的很感激一个让我入门的好例子。具体来说,我不太明白的是如何将接口函数放在我的公共头文件中,私有变量/函数放在我的私有头文件中?谢谢!

修改

也许我没有正确处理我的问题,但我的意思是,例如,我有myMath.h和myMath.cpp,myMath.h有:

class myMath{
public:
    void initialise(double _a, double _b);
    double add();
    double subtract();

private:
    double a;
    double b;
};

myMath.cpp具有函数的实现。我怎样才能使myMath.h只有三个公共函数,而私有变量在另一个文件中定义(例如myMath_i.h),这三个文件就是这样我创建静态库之后用户只需要myMath.h。这也意味着myMath.h不能#include myMath_i.h。如下所示:

myMath.h:

class myMath{
public:
    void initialise(double _a, double _b);
    double add();
    double subtract();
}

和myMath_i.h:

class myMath{
private:
    double a;
    double b;
}

当然那是不可能的,因为那时我将重新定义myMath类......

5 个答案:

答案 0 :(得分:22)

您有两个头文件MyClass.h和MyClass_p.h以及一个源文件:MyClass.cpp。

让我们来看看里面的内容:

MyClass_p.h:

// Header Guard Here
class MyClassPrivate
{
public:
    int a;
    bool b;
    //more data members;
}

MyClass.h:

// Header Guard Here
class MyClassPrivate;
class MyClass
{
public:
    MyClass();
    ~MyClass();
    void method1();
    int method2();
private:
    MyClassPrivate* mData;
}

MyClass.cpp:

#include "MyClass.h"
#include "MyClass_p.h"

MyClass::MyClass()
{
    mData = new MyClassPrivate();
}

MyClass::~MyClass()
{
    delete mData;
}

void MyClass::method1()
{
    //do stuff
}

int MyClass::method2()
{
    return stuff;
}

将您的数据保存在MyClassPrivate中并分发MyClass.h。

答案 1 :(得分:10)

您可以在单独的头文件(或一组文件)中声明要向库用户公开的所有接口和常量,并将其放入“inc”子目录 - 这些头将是“public”。您还将使用其他头文件来声明您不希望公开的类和内容,因为它们是实现细节 - 您将这些文件放入“src”子目录 - 这些将是“私有”。

通过这种方式,用户将被提示他必须只包含公共标题 - 那些位于“inc”中的标题,只有那些标题包含他真正需要的东西,而所有其他标题都是“私有”的除非他想阅读实施内容,否则他的兴趣领域。

当您将库作为二进制文件(静态库或动态库)发布时,您只需复制“inc”内容和编译结果 - 这些对用户来说已经足够了,这样他就看不到您的实现源。

答案 2 :(得分:2)

公共标头是图书馆用户所需的标头。私有头是编译库所需的,但库用户不需要。执行拆分可能非常棘手,而且许多库根本不会打扰。

答案 3 :(得分:2)

我实际上发现双头一源的方法很脆弱。如果您在更改'private'标头后忘记更新'public'标头,您的代码可能会编译,然后在运行时将其分段错误。我曾经多次遇到这种情况,所以我更喜欢编写不会编译的代码,除非一切都正确。

MyClass.cpp的实现方式如下:

#define MYCLASS_IMPL
#include "MyClass.h"

// Implementation follows
...

MyClass.h是有趣的一点:

#ifdef MYCLASS_IMPL
#include everything needed for the private: section
#endif

#include everything needed for the public: section only

class MyClass
{
public:
    // Everything that's public

#ifdef MYCLASS_IMPL
private:

    // Implementation details

#endif
};

如果目标是隐藏实现细节(例如封闭库),则可能需要采用双头方法。如果您不想仅仅为了使用类而拖入依赖项,那么单标题方法可以是一个简单而强大的解决方案。


解决Arton的问题:自从我看过这个问题已经有一段时间了,但我认为问题与基于公共标头实例化对象有关,然后假定使用私有标头的不同对象大小。在运行时,对象的偏移量不匹配,导致内存粉碎。似乎erenlender的答案涵盖了公共/私人类对的这种情况。

答案 4 :(得分:0)

我想知道同样的事情,因为我从C转换为C ++作为我的主要编程语言。我想最好的方法是使用接口(C ++中的抽象类):你发布一个公共接口,你的私有实现只是使用接口作为基类。

相关问题