C++一个标题多个来源

发布于 2024-12-01 11:38:00 字数 621 浏览 0 评论 0原文

我有一个大类 Foo1

class Foo {
public:
    void apples1();
    void apples2();
    void apples3();

    void oranges1();
    void oranges2();
    void oranges3();
}

拆分类不是一个选项2,而是 foo.cpp文件已经变得相当大。将类的定义保留在 foo.h 中并将函数的实现拆分为 foo_apples.cppfoo_oranges.cpp< 是否存在任何重大设计缺陷/代码>。

这里的目标纯粹是为了我自己和其他开发包含此类的系统的开发人员的可读性和组织性。


1“大”表示大约 4000 行,不是机器生成的。
2为什么?嗯,苹果和橙子实际上是在图上运行的算法类别,但彼此使用得相当广泛。它们可以分开,但由于工作的研究性质,我不断地重新设计每个算法的工作方式,我发现这些算法(在早期阶段)与经典的 OOP 原则不太吻合。

I have a large class Foo1:

class Foo {
public:
    void apples1();
    void apples2();
    void apples3();

    void oranges1();
    void oranges2();
    void oranges3();
}

Splitting the class is not an option2, but the foo.cpp file has grown rather large. Are there any major design flaws to keeping the definition of the class in foo.h and splitting the implementation of the functions into foo_apples.cpp and foo_oranges.cpp.

The goal here is purely readability and organization for myself and other developers working on the system that includes this class.


1"Large" means some 4000 lines, not machine-generated.
2Why? Well, apples and oranges are actually categories of algorithms that operate on graphs but use each other quite extensively. They can be separated but due to the research nature of the work, I'm constantly rewiring the way each algorithm works which I found for me does not (in the early stage) jive well with the classic OOP principles.

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

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

发布评论

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

评论(4

一紙繁鸢 2024-12-08 11:38:00

将类的定义保留在 foo.h 中并将函数的实现拆分为 foo_apples.cpp 和 foo_oranges.cpp 是否存在重大设计缺陷。

挑刺:将类的声明保留在foo.h中并将方法定义分为foo_apples.cpp 和 foo_oranges.cpp。

1)苹果和橙子可能使用相同的私有程序。一个例子是在匿名名称空间中找到的实现。

在这种情况下,一项要求是确保您的静态数据没有被多重定义。如果内联函数不使用静态数据(尽管它们的定义可能会多次导出),那么它们并不是真正的问题。

为了克服这些问题,您可能会倾向于利用类中的存储——这可能会通过增加原本隐藏的数据/类型来引入依赖关系。无论哪种情况,它都会增加复杂性或迫使您以不同的方式编写程序。

2)增加了静态初始化的复杂性。

3)它增加了编译时间,

我在大型程序中使用的替代方案(顺便说一句,许多开发人员讨厌)是创建一个导出的本地标头的集合。这些标头仅对包/库可见。在您的示例中,可以通过创建以下标头来说明: Foo.static.exported.hpp (如果需要)+ Foo.private.exported.hpp (如果需要) + Foo.apples.exported.hpp + Foo.oranges.exported.hpp

那么你可以像这样编写 Foo.cpp:

#include "DEPENDENCIES.hpp"
#include "Foo.static.exported.hpp" /* if needed */
#include "Foo.private.exported.hpp" /* if needed */
#include "Foo.apples.exported.hpp"
#include "Foo.oranges.exported.hpp"

/* no definitions here */

你可以根据你的需要轻松调整这些文件的划分方式。如果您使用 C++ 约定编写程序,那么巨大的 TU 之间很少会发生冲突。如果您像 C 程序员一样编写(大量全局变量、预处理器滥用、低警告级别和自由声明),那么这种方法将暴露许多您可能不关心纠正的问题。

Are there any major design flaws to keeping the definition of the class in foo.h and splitting the implementation of the functions into foo_apples.cpp and foo_oranges.cpp.

to pick nits: Are there any major design flaws to keeping the declaration of the class in foo.h and splitting the definitions of the methods into foo_apples.cpp and foo_oranges.cpp.

1) apples and oranges may use the same private programs. an example of this would be implementation found in an anonymous namespace.

in that case, one requirement would be to ensure your static data is not multiply defined. inline functions are not really a problem if they do not use static data (although their definitions may be multiply exported).

to overcome those problems, you may then be inclined to utilise storage in the class -- which could introduce dependencies by increasing of data/types which would have otherwise been hidden. in either event, it can increase complexity or force you to write your program differently.

2) it increases complexity of static initialization.

3) it increases compile times

the alternative i use (which btw many devs detest) in really large programs is to create a collection of exported local headers. these headers are visible only to the package/library. in your example, it can be illustrated by creating the following headers: Foo.static.exported.hpp (if needed) + Foo.private.exported.hpp (if needed) + Foo.apples.exported.hpp + Foo.oranges.exported.hpp.

then you would write Foo.cpp like so:

#include "DEPENDENCIES.hpp"
#include "Foo.static.exported.hpp" /* if needed */
#include "Foo.private.exported.hpp" /* if needed */
#include "Foo.apples.exported.hpp"
#include "Foo.oranges.exported.hpp"

/* no definitions here */

you can easily adjust how those files are divided based on your needs. if you write your programs using c++ conventions, there are rarely collisions across huge TUs. if you write like a C programmer (lots of globals, preprocessor abuse, low warning levels and free declarations), then this approach will expose a lot of issues you probably won't care to correct.

感情洁癖 2024-12-08 11:38:00

从技术角度来看,这样做根本没有任何惩罚,但我从未见过在实践中这样做。这只是一个风格问题,本着这种精神,如果它可以帮助您更好地阅读课程,那么您不使用多个源文件就会对自己造成伤害。

编辑:除此之外,您是否在物理上滚动源,例如使用鼠标中轮?正如其他人已经提到的,IDE 几乎普遍允许您右键单击函数声明,然后转到定义。即使您的 IDE 不是这种情况,并且您使用记事本或其他东西,它至少也会有 ctrl+f。如果没有找到和替换,我就会迷失。

From a technical standpoint, there is no penalty to doing this at all, but I have never seen it done in practice. This is simply a issue of style, and in that spirit, if it helps you to better read the class, then you would be doing yourself a disservice by not using multiple source files.

edit: Adding to that though, are you physically scrolling through your source, like, with your middle mouse wheel? As someone else already mentioned, IDE's almost universally let you right click on a function declaration, and go to the definition. And even if that's not the case for your IDE, and you use notepad or something, it will at least have ctrl+f. I would be lost without find and replace.

魔法唧唧 2024-12-08 11:38:00

是的,您可以在一个头文件中定义类,并将函数实现拆分到多个源文件中。这通常不是常见的做法,但是它会起作用并且不会产生任何管理费用。

如果这样做的目的只是简单的可读性,那么这样做也许不是一个好主意,因为在多个源文件中使用类函数定义并不常见,并且可能会让某些人感到困惑。

Yes, you can define the class in one header file and split the function implementations accross multiple source files. It is not usually the common practice but yes it will work and there will be no overheads.

If the aim to do so, is just plain readability, then perhaps it is not a good idea to do so, because it is not so common practice to have class function definitions accross multipls source files and might just confuse someone.

奶茶白久 2024-12-08 11:38:00

实际上,我没有看到任何拆分实现的理由,因为其他开发人员应该使用接口,而不是实现。

此外,任何普通的 IDE 都提供从函数声明跳转到其定义的简单能力。所以没有理由手动搜索函数实现。

Actually i don't see any reasons to split implementation because other developers should work with the interface, but not the implementation.

Also any normal IDE provide an easy ability to jump from function declaration to it's defenition. So there is no reason to search the function implementations manually.

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