我正在用C ++编写一个库,并且有一些与模块一起工作的函数。一个例子如下:
void connect(Module *a, Module *b);
问题是,如果接受的函数也引用它有时会很方便(某些模块可能在堆栈上分配,而某些模块在堆上并且所有的& s和* s很快就会变得无聊和混乱)
现在我有内联函数,它接受引用,将它们转换为指针并调用原始函数。
inline void connect(Module &a, Module &b){
connect(&a, &b);
}
我不太喜欢这个解决方案,因为对于更多的函数,它会编写很多代码来编写,读取,编译,...
正在考虑的另一件事是添加Module::operator Module *()
,它必须返回this
。
您对此有何看法?我错过了没有任何史诗般失败的可能吗?
感谢。
答案 0 :(得分:15)
为什么不用
调用函数connect(&a, &b);
就像你的内联函数一样,只要你用引用来调用它?这清楚地表明函数需要指针,而a
和b
不是指针。您只需要输入两个以上的字符。
答案 1 :(得分:8)
任何时候使用运算符重载,都会增加史诗失败的可能性。问题是你知道你不是指*
作为标准指针运算符,而是天真地读取你的代码的人不会。
最好的解决方案是返回并重构/重新考虑您的代码,因此您不需要两个接口来进行相同的操作,
答案 2 :(得分: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);
}
答案 3 :(得分:4)
正如您所观察到的,您可以重载函数以获取指针或引用,但我会拒绝这样做仅仅是为了方便而且坚持一个函数 - 这就是所有主要库的工作方式。
在该函数中使用哪种参数类型?这取决于我的个人准则:
如果NULL对象有意义,可以使用指针。
如果常见的用例是通常动态创建传递的对象,请使用指针。
如果实现在内部使用指针,请使用指针。
否则,请使用参考。
答案 4 :(得分:3)
我始终遵循Google的C ++风格指南中列出的惯例:
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments
基本上只说使用const&和*用于其他一切。我认为它有助于明确哪些参数是无法修改的输入(const& s),以及哪些内容将被修改(*'s)。如果你遵循这样的约定,你可以避免挖掘源代码。
指针确实不坏,所以没有理由回避它们。事实上,大部分时间它只意味着使用“ - >”代替 ”。”解除引用,看起来更酷,非常值得编写更清晰的代码。
答案 5 :(得分:1)
我非常不愿意这样做 - 这可能是一个令人困惑的界面。
一般来说,我更喜欢使用const引用的接口,但是如果传入的对象将被修改,我倾向于优先于非const引用的指针,因为它为接口的用户提供了对象的指示传入可能会被修改。
答案 6 :(得分:1)
您需要两个函数的原因是因为指向模块的指针基本上与参考模块不同。没有解决这个问题。
对我而言,指针很糟糕。总是。只有在需要某些东西的地址而不是某些东西的引用时才使用它们。您很少需要对象的实际地址。我会做以下事情:
此外,您可能需要调查常量。
答案 7 :(得分:0)
我会在公共API中避免内联。
const&在可能的情况下是优选的。或者*
我不知道这些事情是如何联系的,或者'a'与'b'有什么关系
void connect(Module *a, Module *b);
重新安排模块界面更明确是否有意义
Module a;
a.connectOutput(b);
命名参数有助于上下文;)