重载一个函数同时获取指针或引用是不是一种糟糕的做法
Is it bad practice to overload a function to take both a pointer or a reference?
例如,如果我有一个结构FooSpec
:
struct FooSpec { /* lots of data */ };
将以下两个都作为重载函数提供是不是一种糟糕的做法?还是我应该选择一个并坚持下去?
Foo *createFoo(const FooSpec *spec) { /* ... */ }
Foo *createFoo(const FooSpec &spec) { return createFoo(&spec); }
两者兼而有之会引发意想不到的问题吗?
应该只有一种方法来做特定的事情。这将使代码对用户更加清晰。因此,根据语义,您应该只选择一个:
-
如果
nullptr
是一个要传递给createFoo
的有意义的值,那么声明该函数接受指针。 -
如果
nullptr
不应该传递给createFoo
,那么将参数声明为引用,以使编译器对试图传递nullptr
的人大喊大叫。
现在,代码的用户会说"啊,我可以给那个函数传递一个null,很酷!"或者"好吧,这个函数需要一个实际的对象才能正常工作"。
在整个项目中坚持这个约定,以使代码的接口更加连贯。
或者正如WhozCraig所说,
选择合适的型号并告诉客户"这是你的界面。"
我能想出一个稍微有用的理由来做这件事。
Foo*
版本可以检查null,处理该情况,如果不使用引用情况。
Foo&
则不能检查是否为空。
这让调用者说"我知道这不是null,因为我检查了",从而在函数中保存了一个分支。
然而,一旦该方法的成本通过非常低的阈值,这种好处(节省分支)就毫无意义了。
软件代码库不是一个静态对象,它是随着使用它的人的需求而发展的。如果一个令人困惑的界面是"糟糕的做法"(我宁愿说这是一件愚蠢的事情),那么代码库可能会在重构和代码改进的过程中发展到这种情况。
在这种情况下,如果您正在迁移编码约定以使用引用而不是常量指针(或者相反,但这对我来说没有多大意义),这并不是一种糟糕的做法。这里的坏做法可能是进行这些演变,而不是记录它,因为其他人不知道其中一种方法被弃用,或者只是不知道该使用哪种方法。
还有可能传递带有常量指针的nullptr_t
(或像我这样的老计时器的NULL
指针)。我不确定这样做的好处,因为您可以在方法的参数上重载方法,但同样,在不断变化的API环境中,这是有意义的。
†它还活着
- 在调用接收数组的方法时,模板化数组大小是不是一种糟糕的做法
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 在枚举类型上使用std::max是不是一种糟糕的做法
- std::元组大小,是不是错过了优化?
- boost::P rogram_options 一种判断值是从命令行还是 ini 文件的方法?
- 拥有相同方法的静态和非静态版本是不是设计不好
- 他是不是很贪婪
- 在DLL中分配内存并将其指针提供给客户端应用程序,这是不是一种糟糕的做法
- 在C++代码中使用C风格的注释是不是一种糟糕的做法
- 矢量的一种交换方式是可能的
- 在main.cpp中而不是在头文件中定义函数是不是一种糟糕的做法
- 重载一个函数同时获取指针或引用是不是一种糟糕的做法
- 让子对象引用其父对象而不是指针,这是不是一种糟糕的做法
- 嵌套渲染循环是不是一种糟糕的做法
- 在操作数据成员时:以下哪一种被认为是最佳实践
- 运算符==对其操作数进行变异是不是一种糟糕的做法
- 在c++中,依赖局部对象以相反的构造顺序被析构是不是一种不好的做法?
- 将函数代码与预处理器指令混合在一起是不是一种糟糕的做法
- C++:为了便于访问,在类中使用静态容器来包含指向其所有对象的指针是不是一种糟糕的做法
- POCO C++SAX解析器:如果xml文档编码是ANSI,那么下一条语句不是读取并抛出编码错误异常