C++ 私有/公共标头示例?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2272735/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Private/public header example?
提问by chocobo_ff
Can someone please give me an example of how public and private headers work? I have done some reading on the net but I can't seem to find much useful information with sample codes. I was advised that I should use private headers to separate the public and private parts of my code for creating a static library. After some reading I have a general idea of how it works, but would really appreciate a good example to get me started. Specifically, what I don't quite understand is how to put the interface functions in my public header, and the private variables/functions in my private header? Thanks!
有人可以给我一个公共和私人标题如何工作的例子吗?我在网上做了一些阅读,但我似乎无法通过示例代码找到很多有用的信息。有人建议我应该使用私有头文件来分隔代码的公共部分和私有部分,以创建静态库。经过一些阅读,我对它的工作原理有了一个大致的了解,但真的很感激一个让我开始的好例子。具体来说,我不太明白的是如何将接口函数放在我的公共头文件中,以及如何将私有变量/函数放在我的私有头文件中?谢谢!
EDIT:
编辑:
Maybe I'm not wording my question right, but what I meant is, for example, I have myMath.h and myMath.cpp, and myMath.h has:
也许我的问题措辞不正确,但我的意思是,例如,我有 myMath.h 和 myMath.cpp,而 myMath.h 有:
class myMath{
public:
void initialise(double _a, double _b);
double add();
double subtract();
private:
double a;
double b;
};
And myMath.cpp has the implementations of the functions. How can I make it so that myMath.h only has the three public functions, and the private variables are defined in another file (e.g. myMath_i.h), and these three files are in such a way that after I create a static library, only myMath.h is needed by users. This also means myMath.h cannot #include myMath_i.h. So something like:
而 myMath.cpp 有函数的实现。怎样才能让myMath.h只有三个公共函数,而私有变量定义在另一个文件(例如myMath_i.h)中,而这三个文件是这样的,在我创建了一个静态库之后,用户只需要 myMath.h。这也意味着 myMath.h 不能 #include myMath_i.h。所以像:
myMath.h:
我的数学.h:
class myMath{
public:
void initialise(double _a, double _b);
double add();
double subtract();
}
and myMath_i.h:
和 myMath_i.h:
class myMath{
private:
double a;
double b;
}
Of course that's not possible because then I'll be redefining the class myMath...
当然这是不可能的,因为那样我将重新定义 myMath 类......
采纳答案by erelender
You have two header files MyClass.h and MyClass_p.h and one source file: MyClass.cpp.
您有两个头文件 MyClass.h 和 MyClass_p.h 以及一个源文件:MyClass.cpp。
Lets take a look at what's inside them:
让我们来看看它们的内部结构:
MyClass_p.h:
MyClass_p.h:
// Header Guard Here
class MyClassPrivate
{
public:
int a;
bool b;
//more data members;
}
MyClass.h:
我的类.h:
// Header Guard Here
class MyClassPrivate;
class MyClass
{
public:
MyClass();
~MyClass();
void method1();
int method2();
private:
MyClassPrivate* mData;
}
MyClass.cpp:
我的类.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;
}
Keep your data in MyClassPrivate and distribute MyClass.h.
将您的数据保存在 MyClassPrivate 中并分发 MyClass.h。
回答by sharptooth
You can declare all the interfaces and constants you want to expose to the library user in a separate header file (or a set of files) and put it into "inc" subdirectory - those headers will be "public". You will also use other header files to declare classes and stuff you don't want to expose since theay are implementation details - you will put those files into "src" subdirectory - those will be "private".
您可以在单独的头文件(或一组文件)中声明要向库用户公开的所有接口和常量,并将其放入“inc”子目录 - 这些头将是“public”。您还将使用其他头文件来声明您不想公开的类和内容,因为它们是实现细节——您将这些文件放入“src”子目录中——那些将是“私有的”。
This way the user will be given a hint that he has to include only the public headers - those that are in "inc" and only those headers contain the stuff he really needs, while all other headers are "private" and out of his interest area unless he wants to read into the implementation.
这样,用户将得到提示,他必须只包含公共标题 - 那些在“inc”中的标题,并且只有那些标题包含他真正需要的东西,而所有其他标题都是“私有的”并且不符合他的兴趣除非他想阅读实施。
When you publish your library as binary - either static or dynamic library - you only copy the "inc" contents and the compilation result - those are enough for the user and this way he doesn't see your implementation sources.
当您将库发布为二进制文件时 - 无论是静态库还是动态库 - 您只需复制“inc”内容和编译结果 - 这些对用户来说就足够了,这样他就看不到您的实现源。
回答by Daniel Schuler
I've actually found the two-header-one-source approach to be fragile. If you forget to update the 'public' header after changing the 'private' header, your code may compile, and then segfault somewhere else at run time. I've had this happen to me a few times, so I prefer to write code that won't compile unless everything is correct.
我实际上发现二头一源的方法很脆弱。如果您在更改“私有”标头后忘记更新“公共”标头,则您的代码可能会编译,然后在运行时在其他地方出现段错误。我遇到过几次这种情况,所以我更喜欢编写除非一切都正确否则无法编译的代码。
MyClass.cpp is implemented like this:
MyClass.cpp 是这样实现的:
#define MYCLASS_IMPL
#include "MyClass.h"
// Implementation follows
...
MyClass.h is the interesting bit:
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
};
If the goal is to hide implementation details (for e.g. a closed library), you may need to go with the two-header approach. If you don't want to drag in dependencies just to use a class, the single-header approach can be a simple and robust solution.
如果目标是隐藏实现细节(例如一个封闭的库),你可能需要采用双头方法。如果您不想仅仅为了使用类而拖入依赖项,那么单头方法可以是一个简单而强大的解决方案。
To address Arton's question: It's been a while since I've looked at this, but I think the issue had to do with instantiating objects based on the public header, then assuming a different object size with the private header. At run time, an offset into the object wouldn't match, causing a memory smash. It seems like erenlender's answer covers this case with a public/private class pair.
解决 Arton 的问题:我已经有一段时间没有看过这个了,但我认为这个问题与基于公共标头实例化对象有关,然后使用私有标头假设不同的对象大小。在运行时,对象的偏移量不匹配,导致内存崩溃。似乎 erenlender 的回答涵盖了这种情况,其中包含公共/私有类对。
回答by Daniel Schuler
Public headers are those needed by the users of the library. Private headers are those needed to compile the library, but which are not needed by library users. Performing the split can be quite tricky, and a lot of libraries simply don't bother.
公共标头是图书馆用户需要的标头。私有头文件是编译库所需但库用户不需要的头文件。执行拆分可能非常棘手,很多库根本不会打扰。
回答by Spidey
I was wondering the same thing since I'm switching from C to C++ as my main programming language. I guess the best way is to use interfaces (abstract classes in C++): you publish a public interface, and your private implementation just use the interface as base class.
我想知道同样的事情,因为我从 C 切换到 C++ 作为我的主要编程语言。我想最好的方法是使用接口(C++ 中的抽象类):您发布一个公共接口,而您的私有实现只是将接口用作基类。

