0

该库提供了一个派生类,派生类作为模板参数。

例子:

class userclass : public lib::superclass<userclass>
{}

如您所见,要输入的内容很多。并且“用户类”应该始终作为公共派生以使其正常工作。所以我想出了两个看起来像这样的宏:

#define SUPER(x) public lib::superclass<x>
#define SUPERCLASS(x) class x : public lib::superclass<x>

用户现在可以键入其中任何一个。

class userclass : SUPER(userclass)
{}

SUPERCLASS(userclass)
{}

但主要问题是宏 SUPER 和 SUPERCLASS 存在于用户全局命名空间中的速度与包含标题一样快。

我可以/应该:

  1. 有办法保留命名空间要求但仍默认为公共派生?
  2. 按原样使用宏。
  3. 只需要求用户写出完整的“public lib::superclass”。

我正在使用 vs 11,并且该库针对 Windows 开发人员。

4

3 回答 3

6

使用宏的第一条规则是“不要,如果有任何其他解决方案”。在这种情况下,还有另一种解决方案,所以摆脱它们。

其次,你的宏弊大于利,因为人们不知道他们仅仅通过阅读它来扩展什么,而完整的定义却知道。说真的,你节省了非常少的字符数,但在可读性方面却付出了巨大的代价。简单地写出继承要好得多。

于 2013-02-02T12:41:56.973 回答
2

这真的不是很多打字。我见过很多不应该缩短的更长的行。用宏隐藏它只会混淆你的代码。如果我快速看一下您的SUPERCLASS(userclass) {},我几乎可以猜到它是一个类(我不喜欢根据猜测使用库),但我不知道它或其父级是否被调用userclass(或两者都没有)或它使用什么样的继承。这意味着您必须记录它,并迫使人们在需要时查找它。

所以正确的答案是选项 3 - 不要使用宏。

如果你真的真的需要在你的库中使用一个宏,给它一个库特定的前缀。这与您将获得命名空间宏一样接近。

于 2013-02-02T12:42:45.923 回答
0

我投票给 3。只需要求用户写出完整的“public lib::superclass”。

在以下情况下,库中的宏可能很有用:

  • 真的有很多要写
  • 有些东西必须写好几次
  • 或者你想隐藏一个丑陋的实现细节,而语言不允许你这样做。

但在你的情况下:

  • 写的不多,
  • 是的,你必须输入两次类名,
  • 你不想隐藏你是子类化的事实,甚至你正在写一个类!

我不认为类名的重复——一个积极的观点——是值得的。特别是因为您将隐藏class关键字并给读者造成相当大的混乱。

无论如何,如果一个库使用宏,习惯上将库名放在所有宏的前面:

#define MY_FANCY_LIBRARY_NAME_SUPER(x) public lib::superclass<x>

但是现在你并没有节省那么多打字......

PS:记住编程的黄金法则:

代码只写一次,永远读下去,因此它应该易于阅读,而不是易于编写。

于 2013-02-02T12:46:07.280 回答