嵌套命名空间,纠正静态库设计问题

发布于 2024-09-05 05:54:05 字数 656 浏览 7 评论 0原文

我目前正在开发一个相当大的静态库,完成后将被一些工具使用。现在,由于这个项目比我迄今为止参与的任何项目都要大,我意识到是时候为该项目考虑一个好的结构了。使用命名空间是这些逻辑步骤之一。

我当前的方法是将库分成几个部分(这些部分不是独立的,但它们的目的需要这样的分离)。我有一个“核心”部分,它现在只包含一些非常常见的类型定义和常量(由库的许多不同部分使用)。其他部分例如一些“utils”(哈希等)、文件 I/O 等。每个部分都有自己的命名空间。我几乎完成了“utils”部分,并意识到我的方法可能不是最好的。问题(如果我们想这样称呼它)是在“utils”命名空间中,我需要来自“core”命名空间的某些内容,这会导致包含核心头文件和许多 using 指令。

所以我开始认为这可能不是一件好事,应该以某种方式改变。我的第一个想法是使用嵌套命名空间来拥有类似 core::utils 的东西。由于这需要一些大量的重构,我想先在这里问一下。你怎么认为?你会怎么处理这个?或者更一般地说:如何在命名空间和代码组织方面正确设计静态库?如果有一些关于它的指南或文章,也请提及。谢谢。

注意:我确信有更多好的方法,而不仅仅是一种。请随意发表您的想法、建议等。因为我正在设计这个库,所以我希望它非常好。目标是使其尽可能干净和快速。唯一的问题是我将不得不集成大量现有代码并重构它,这确实是一个痛苦的过程(叹息) - 这就是为什么良好的结构如此重要)

I'm currently in the process of developing a fairly large static library which will be used by some tools when it's finished. Now since this project is somewhat larger than anything i've been involved in so far, I realized its time to think of a good structure for the project. Using namespaces is one of those logical steps.

My current approach is to divide the library into parts (which are not standalone, but their purpose calls for such a separation). I have a 'core' part which now just holds some very common typedefs and constants (used by many different parts of the library). Other parts are for example some 'utils' (hash etc.), file i/o and so on. Each of these parts has its own namespace. I have nearly finished the 'utils' part and realized that my approach probably is not the best. The problem (if we want to call it so) is that in the 'utils' namespace i need something from the 'core' namespace which results in including the core header files and many using directives.

So i began to think that this probably is not a good thing and should be changed somehow. My first idea is to use nested namespaces as to have something like core::utils. Since this will require some heavy refactoring i want to ask here first. What do you think? How would you handle this? Or more generally: How to correctly design a static library in terms of namespaces and code organization? If there are some guidelines or articles about it, please mentoin them too. Thanks.

Note: i'm quite sure that there are more good approaches than just one. Feel free to post your ideas, suggestions etc. Since i'm designing this library i want it to be really good. The goal is to make it as clean and FAST as possible. The only problem is that i will have to integrate a LOT of existing code and refactor it, which will really be a painful process (sigh) - thats why good structure is so important)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜味拾荒者 2024-09-12 05:54:05

我自己的方法是每个库使用一个命名空间。我认为嵌套命名空间不会给聚会带来任何好处,除非您喜欢(在键盘上)打字。这对我来说是零问题的。

My own approach is to use one single namespace per library. I don't think nested namespaces bring anything to the party, unless you like typing (on the keyboard). This has worked for me with zero problems.

乱了心跳 2024-09-12 05:54:05

好吧,我认为在 core.h 标头中,您应该有类似

#include <string>
#include <iostream>
namespace core
{
    typedef std::string mystring;
    #define mycout std::cout
}

And not one using 指令的内容,以防止污染全局名称空间。在 utils.h 标头中,您可以使用以下内容:

#include "core.h"
namespace utils
{
    core::mystring stringfunction(core::mystring &stuff)
    {
        core::mystring result;
        // do stuff
        return result;
    }
}

因此,除了 core:: 之外,任何地方都没有 mystring 。它涉及更多的输入,但这就是命名空间的用途,让您自己知道从哪里获取类型/函数/类。

更新

故事的另一面是这样的:

core.h 标头在核心命名空间中声明内容,如上面所示。

utils.h 标头在 core::utils 命名空间中声明内容,之后是 namespace utils = core::utils 语句。这使得这两种方法对于用户来说是相同的,并且允许您在 utils*.h 中编写诸如 mystring 之类的内容,而不是 core::mystring > 标头和 *.cpp 文件。

对于 utils.h 来说是这样的:

#include "core.h"
namespace core
{
    namespace utils
    {
        mystring stringfunction(mystring &stuff)
        {
            mystring result;
            // do stuff
            return result;
        }
    }
}
namespace utils = core::utils; // allow user to type utils::stringfunction

这会稍微清理用户和库代码。

Well, I would think that in the core.h header, you would have stuff like

#include <string>
#include <iostream>
namespace core
{
    typedef std::string mystring;
    #define mycout std::cout
}

And not one using directive, to prevent contaminating the global namespace. In a utils.h header, you would use stuff like:

#include "core.h"
namespace utils
{
    core::mystring stringfunction(core::mystring &stuff)
    {
        core::mystring result;
        // do stuff
        return result;
    }
}

Hence, there is no mystring anywhere, except in core::. It involves a bit more typing, but that's what namespaces are for, letting yourself know where you're getting the type/function/class from.

UPDATE

The other side of the story is something like this:

core.h header declaring stuff in core namespace like above.

utils.h header declaring stuff in core::utils namespace, and after that a namespace utils = core::utils statement. This makes the two approaches identical to the user, and allows you to write stuff like mystring instead of core::mystring in the utils*.h headers and *.cpp files.

Something like this for a utils.h:

#include "core.h"
namespace core
{
    namespace utils
    {
        mystring stringfunction(mystring &stuff)
        {
            mystring result;
            // do stuff
            return result;
        }
    }
}
namespace utils = core::utils; // allow user to type utils::stringfunction

This cleans up user- and library code a bit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文