1

我正在用 C++ 编写一个库,并且有一些可与模块一起使用的函数。一个示例如下所示:

void connect(Module *a, Module *b);

问题是,如果函数也接受引用,有时会很方便(一些模块可能分配在堆栈上,一些在堆上,所有 &s 和 *s 很快就会变得无聊和混乱)。

现在我有内联函数,它接受引用,将它们转换为指针并调用原始函数。

inline void connect(Module &a, Module &b){
    connect(&a, &b);
}

我不太喜欢这个解决方案,因为对于更多功能,它会产生大量代码来编写、读取、编译......

正在考虑的另一件事是添加Module::operator Module *()将返回的内容this

您对此有何看法?我错过了史诗般的失败的可能性吗?

谢谢。

4

8 回答 8

14

为什么不直接调用函数

connect(&a, &b);

就像在您的内联函数中一样,每当您必须使用引用调用它时?这清楚地表明该函数接受指针,而 thatab不是指针。您只需再输入两个字符。

于 2009-04-10T14:47:24.710 回答
8

任何时候使用运算符重载,都会增加史诗般失败的可能性。问题是知道您的意思不是*标准的指针运算符,但是天真地阅读您的代码的人却没有。

最好的解决方案是返回并重构/重新考虑您的代码,因此您不需要两个接口来执行相同的操作,

于 2009-04-10T14:47:28.877 回答
6

我不确定在您的情况下这是否是一个好主意,但通常,您可以使用参数适配器:

struct ModulePtrOrRef
{
  Module * m_p;
  Module(Module * p) : m_p(p) {}
  Module(Module & p) : m_p(&p) {}
}

void connect(ModulePtrOrRef a, ModulePtrOrRef b)
{
  connect_impl(a.m_p, b.m_p);
}
于 2009-04-10T15:14:26.750 回答
4

正如您所观察到的,您可以重载该函数以获取指针或引用,但我会仅仅因为方便而拒绝这样做,并坚持使用一个函数 - 这就是所有主要库的工作方式。

在该函数中使用哪种参数类型?这取决于 - 我的个人准则:

  • 如果 NULL 对象有意义,请使用指针。

  • 如果常见的用例是传递的对象通常是动态创建的,请使用指针。

  • 如果实现在内部使用指针,请使用指针。

  • 否则,使用参考。

于 2009-04-10T14:49:51.367 回答
3

我始终遵循 Google 的 C++ 样式指南中列出的约定:

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments

这基本上说只使用 const & 和 * 其他所有内容。我认为这有助于非常清楚哪些参数是不能修改的输入(const &'s),以及哪些东西将被修改(*'s)。如果您遵循这样的约定,您可以避免挖掘源代码。

指针真的一点也不差,所以没有理由回避它们。事实上,大多数时候它只是意味着使用“->”而不是“.”。取消引用,这看起来更酷,并且非常值得编写更清晰的代码。

于 2009-04-10T15:26:53.010 回答
1

我非常不愿意做这样的事情——这可能是一个令人困惑的界面。

一般来说,我更喜欢使用 const 引用的接口,但如果传入的对象将被修改,我倾向于使用指针而不是非常量引用,因为它给接口的用户一个指示,表明传入的对象可能被修改。

于 2009-04-10T14:48:12.417 回答
1

您需要两个函数的原因是,指向模块的指针从根本上是不同于模块引用的类型。没有办法解决这个问题。

对我来说,指针不好。总是。仅当您需要某物的地址而不是对某物的引用时才使用它们。而且很少需要对象的实际地址。我会做以下事情:

  1. 将基于指针的函数变成基于引用的函数。
  2. 在不必要的地方停止使用指针。您当然应该避免使用指针引用。

此外,您可能想调查 const-ness。

于 2009-04-10T14:49:13.443 回答
0

我会避免在公共 API 中内联。

const & 在可能的情况下优于 & 或 *

我不知道这些东西是如何联系起来的,也不知道“a”与“b”有什么关系

void connect(Module *a, Module *b);

重新安排模块接口更明确是否有意义

Module a;
a.connectOutput(b);

命名参数有助于上下文;)

于 2009-04-10T15:09:00.947 回答