使用#ifdef或继承进行交叉编译哪个更好?

发布于 2024-08-16 18:21:44 字数 1113 浏览 6 评论 0原文

从我的 上一个问题开始关于虚拟和多重继承(在跨平台场景中)-在阅读了一些答案后,我想到可以通过保留服务器和客户端类并用 #ifdefs 替换平台特定的类来简化我的模型(这就是我最初要做的)。

使用这段代码会更简单吗?这意味着至少文件会更少!缺点是它创建了一个有点“丑陋”并且稍微难以阅读的 Foobar 类,因为到处都有 #ifdefs 。请注意,我们的 Unix Foobar 源代码永远不会传递给编译器,因此这与 #ifdef 具有相同的效果(因为我们还使用 #ifdef 来决定什么要调用的平台特定类)。

class Foobar {
public:
  int someData;

#if WINDOWS
  void someWinFunc1();
  void someWinFunc2();
#elif UNIX
  void someUnixFunc1();
  void someUnixFunc2();
#endif

  void crossPlatformFunc();
};

class FoobarClient : public Foobar;
class FoobarServer : public Foobar;

注意:为了更简单的示例,省略了一些内容(ctor 等)。

更新:

对于那些想要详细了解此问题背景的人,我强烈建议浏览相应的 邮件列表线程。从第三篇文章开始,事情开始变得有趣。另外还有一个相关代码提交,您可以使用它可以在这里看到有问题的现实生活代码。

To follow from my previous question about virtual and multiple inheritance (in a cross platform scenario) - after reading some answers, it has occurred to me that I could simplify my model by keeping the server and client classes, and replacing the platform specific classes with #ifdefs (which is what I was going to do originally).

Will using this code be simpler? It'd mean there'd be less files at least! The downside is that it creates a somewhat "ugly" and slightly harder to read Foobar class since there's #ifdefs all over the place. Note that our Unix Foobar source code will never be passed to the compiler, so this has the same effect as #ifdef (since we'd also use #ifdef to decide what platform specific class to call).

class Foobar {
public:
  int someData;

#if WINDOWS
  void someWinFunc1();
  void someWinFunc2();
#elif UNIX
  void someUnixFunc1();
  void someUnixFunc2();
#endif

  void crossPlatformFunc();
};

class FoobarClient : public Foobar;
class FoobarServer : public Foobar;

Note: Some stuff (ctor, etc) left out for a simpler example.

Update:

For those who want to read more into the background of this issue, I really suggest skimming over the appropriate mailing list thread. Thing start to get interesting around the 3rd post. Also there is a related code commit with which you can see the real life code in question here.

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

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

发布评论

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

评论(5

泪痕残 2024-08-23 18:21:44

最好在方法中包含操作的平台相关性质,以便类声明在跨平台上保持相同。 (即,在实现中使用#ifdefs)

如果您不能做到这一点,那么您的类应该是两个完全独立的类,一个用于每个平台。

Preferably, contain the platform dependant nature of the operations within the methods so the class declaration remains the same across platforms. (ie, use #ifdefs in the implementations)

If you can't do this, then your class ought to be two completely separate classes, one for each platform.

长途伴 2024-08-23 18:21:44

我个人的偏好是将 ifdef 魔法推送到 make 文件中,以便源代码尽可能保持干净。然后为每个平台提供一个实现文件。这当然意味着您可以为所有支持的系统提供一个通用的接口。

编辑:

解决跨平台开发的这种下分母设计的一种常见方法是不透明句柄习惯用法。与 ioctl(2) 转义路径相同的想法 - 有一个方法返回为每个平台定义不同的不透明前向声明结构(最好在实现文件中),并且仅在公共抽象不成立时才使用它。

My personal preference is to push ifdef magic into the make files, so the source code stays as clean as possible. Then have an implementation file per platform. This of course implies you can come up with an interface common for all your supported systems.

Edit:

One common way of getting around such a lower denominator design for cross-platform development is an opaque handle idiom. Same idea as ioctl(2) escape route - have a method returning opaque forward-declared structure defined differently for each platform (preferably in the implementation file) and only use it when common abstraction doesn't hold.

还如梦归 2024-08-23 18:21:44

如果您完全确定不会在编译的操作系统上使用其他操作系统的函数,那么使用 ifdef 有很多优点:

  1. 未使用的代码和变量不会被编译到可执行文件中(但是智能链接有助于这里有点)
  2. 可以很容易地看到哪些代码是实时的
  3. 您将能够轻松地包含平台相关的文件。

然而,基于操作系统的分类仍然有它的好处:

  1. 在对一个平台进行更改时,您将能够确保代码在所有平台上进行编译
  2. 代码和设计将更加清晰

后者是通过 ifdefing 中的特定于平台的代码来实现的类体本身,或者只是在编译时定义出不支持的操作系统实例。

If you're fully sure that you won't use functions from the other OS on the one compiled, then using ifdef's has a lot of advantages:

  1. Code and variables non used won't be compiled into the executable (however smart-linking helps here a bit)
  2. It will be ease to see what code is live
  3. You will be able to easily include platform dependent files.

However, classing based on OS can still have it's benefits:

  1. You'll be able to be sure that the code compiles on all platforms when doing changes for one
  2. The code and design will be cleaner

The latter is achieved by ifdefing platform-specific code in the class bodies themselves, or just ifdefing out the non-supported OS instances in compilation.

天生の放荡 2024-08-23 18:21:44

我的偏好是将平台特定问题推送到最叶模块,并尝试将它们包装到一个通用接口中。将特定的方法、类和函数放入单独的翻译单元中。让链接器和构建过程确定要组合哪些特定的翻译单元。这使得代码更加简洁并且调试时间更加容易。

根据经验,我有一个使用 #ifdef VERSION2 的项目。我花了一周时间进行调试,因为一个模块使用了 #ifdef VERSION_2。如果所有版本 2 特定代码都在版本 2 模块中,则更容易捕捉到这一微妙之处。

My preference is to push platform specific issues to the leaf-most modules and try to wrap them into a common interface. Put the specific methods, classes and functions into separate translation units. Let the linker and build process determine which specific translation units to combine. This makes for much cleaner code and easier debugging times.

From experience, I had a project that used #ifdef VERSION2. I spent a week in debugging because one module used #ifdef VERSION_2. A subtlety that would be easier to catch if all the version 2 specific code was in version 2 modules.

没有你我更好 2024-08-23 18:21:44

使用 #ifdefs 来表示特定于平台的代码是惯用的;特别是因为如果在另一个平台上启用了某个平台的代码,则该代码甚至无法编译。对我来说听起来是个好方法。

Having #ifdefs for platform specific code is idiomatic; especially since code for one platform won't even compile if it's enabled on another. Sounds like a good approach to me.

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