使用#include将大块重复代码放入单独的文件中是否正常和/或正常?

Ste*_*aus 7 c++ code-readability

我一直在解剖一些代码,我看到了一些我以前从未见过的东西,我想知道这是不是一个好/坏的做法,如果这是正常的.

基本上有一个头文件,带有类定义,用于具有一堆(大约90个)纯虚函数的类.这些虚函数有很多,所以它们都放在一个单独的文件中,然后包含在类定义中,如下所示:

foo.h中

class Foo
{
public:
    virtual ~Foo() {};
    #define FOO_VIRTUAL_IMPL = 0
    #include "Foo_prototypes.h"
};
Run Code Online (Sandbox Code Playgroud)

Foo_prototypes.h

#if ! defined(FOO_VIRTUAL_IMPL)
# define FOO_VIRTUAL_IMPL
#endif

virtual void doSomething() FOO_VIRTUAL_IMPL;

virtual void doSomethingElse() FOO_VIRTUAL_IMPL;
Run Code Online (Sandbox Code Playgroud)

使用定义宏也是常见的(即允许相同的包含文件用于纯虚拟和普通虚拟功能)?是经常使用这种东西,还是只是为了节省一点时间/精力的小黑客?

我想这些东西让代码看起来对我来说不太可读,但可能只是因为我不习惯这些技巧,一旦我习惯了它们,我就会更好地阅读这种代码.

有问题的代码是Interactive Brokers的C++ API,如果有人关心在上下文中看到它.相关文件是:EWrapper.h和TestCppClient.h以及EWrapper_prototypes.h.

Ord*_*mae 7

Wellll,这不是我称之为风格良好的代码.是的,从技术上讲,你可以在这种地方包含标题,但它不完全是标准的,所以我不推荐它.总的来说,"远离语言的尘埃落定".但是,如果你真的想做那种事,你可以.但是,不遵循标准做法可能会产生两种效果.

  1. 非标准代码通常难以阅读,因此较少的人能够或愿意贡献.

  2. 非标准代码可能会有更多的错误,而不是因为它不是标准的.

我之前提到的错误的一个例子是FOO_VIRTUAL_IMPL工作方式.#define不仅限于范围,因此所有代码都可以看到这一点.它#define在一个标题中真的很容易,而不是在另一个标题中定义它.这会导致第二个标头中的所有虚函数都是纯虚拟的,可能不是您想要的.

编辑:另外,正如Caleth所说,如果你的课程需要那么多重复的代码,那么完全重新设计你的课程会更好.


小智 5

这里有几个问题.

如果你有一个具有相同纯虚函数的类一遍又一遍,它就是一个定义的接口.绝对没有理由不在明确定义的命名界面中进行包装.现代IDE将在实现这些接口时为您提供支持(因此不需要宏魔法).

通常,使用宏是不好的.我们不接受任何代码审查中的宏编程.查看C++ ISO指南以获取更多信息:

宏是bug的主要来源.宏不遵守通常的范围和类型规则.宏确保人类读者看到与编译器看到的不同的东西.宏使工具构建复杂化.

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-macros


Ala*_*les 1

更安全的实施方式是:

#define FOO_PROTOTYPES(FOO_VIRTUAL_IMPL)\
virtual void doSomething() FOO_VIRTUAL_IMPL;\
virtual void doSomethingElse() FOO_VIRTUAL_IMPL;

class Foo
{
public:
    virtual ~Foo() {};
    FOO_PROTOTYPES( = 0 );
};

class FooImpl : public Foo
{
public:
    virtual ~FooImpl() {};
    FOO_PROTOTYPES( override );
};
Run Code Online (Sandbox Code Playgroud)

所有内容都在一个标头中,避免FOO_VIRTUAL_IMPL在另一个标头中意外使用一个标头中定义的值。

但是,如果您的类有足够的方法使此类构造有价值,那么可能是时候将您的类重构为更小的类了。