例如,我们有一个函数,其结果是一个数组。我经常看到这样的事情:
void func(some_args, result_array){//some code//}
因为你可以看到函数没有返回数组,我们将它作为参数传递。
第二种情况如下:
float* func(some_args){ //some code// return result_array;}
是否有关于此的约定或这仅仅是个人偏好?就个人而言,我注意到第二个声明,它返回一个数组,是非常罕见的。这有什么理由吗?
UPD :我很抱歉不精确。当然,在第二种情况下,我暗示了一个指向数组的指针。
答案 0 :(得分:4)
不同之处在于所有权。
void func(some_args, float*);
VS
float* func(some_args);
在第一种形式中,很清楚谁负责为阵列提供内存。在第二个原因中存在歧义:您调用的函数是拥有内存还是正在传输给您。谁负责delete
[]它?
char* s = strdup("hello");
// I have to remember to 'free()' what was strdup'd
// but what if I think "this is C++" and delete[] it?
- 编辑 -
这可能部分地促成了C ++ 11s智能指针(std::unique_ptr
和std::shared_ptr
)的发展,因此比所讨论的两个更好的选择是使用其中一个。
std :: unique_ptr func(some_args);
这明确指出“我会给你一个你负责的东西”。
答案 1 :(得分:2)
数组是C ++类型系统中的“二等”公民。
你应该做的是返回一个容器(例如std::vector
),因为这些容器由语言统一处理。
数组的问题是
std::vector
是围绕动态分配的数组的瘦包装,但可以像任何其他值类型一样传递给函数或进行操作,并且大小也是运行时值。当然,没有黄金法则可以永远应用......但是大多数情况下,在C语言中使用C ++中的数组时,使用std::vector
代替。
答案 2 :(得分:1)
是否有任何约定
是的,有一个'惯例'对于这个问题。
大多数专业环境都有编码标准。还将有同行评审和(可能)静态分析仪来检测和执行标准。
例如," Google C ++风格指南" (猜测它是多么容易找到),识别参数排序:
定义函数时,参数顺序为:输入,然后输出。
C / C ++函数的参数是函数的输入,输出 从功能,或两者。输入参数通常是值或 const引用,而输出和输入/输出参数将是 非常量指针。订购功能参数时,全部放入 任何输出参数之前的仅输入参数。特别是,做 不要仅仅因为它们而将新参数添加到函数的末尾 是新的;在输出参数之前放置新的仅输入参数。
这不是一个严格的规则。既是输入又是输入的参数 输出(通常是类/结构)使水变得混乱,并且一如既往 与相关功能的一致性可能需要您弯曲规则。
我还要补充一点,编写的代码可能不符合本指南。我的最后一次演出坚持要求编码人员将他们的代码与任何相关代码相匹配......不是一个“清晰”的代码。那里的目标。
你不恰当地提出你的第一个案件:
void func(some_args, result_array){//some code//}
因此,让我尝试一下更多提示的演示文稿:
Google C ++风格指南讨论的惯例最好以
的形式呈现void func(T1 argIn1,
T2 argIn2,
const T3& argIn3,
std::vector<T4>& argOut4);
因此,argIn1和argIn2按值传递给func,并且显然是输入。
argIn3是const ref,也是一个输入。这是如何将大输入传递给函数而不会产生副本的成本。
argOut4由非常量引用传递,在这种情况下,肯定是输出,但可能被视为输入和输出。
有很多代码示例(例如linux api等),函数返回一些东西。您可以自行计算并确定是否有任何结果适用于您的工作。我可以找到很多(例如memcmp),其中返回值是重要结果,但我感觉(我还没有确认)大多数(或者更多)历史函数返回状态...成功时可能为0,或者-1当错误和errno中的值来描述时。
因此,这些天,我更喜欢返回std :: string。当返回size()为0时,没有发生错误,否则,将在字符串中捕获错误描述。
你的第二个案例也说不好。函数和方法只能返回1个东西......它可以是一个类或结构并填充信息,但函数语义只能返回一个项目。
遵循风格指南(任何编码标准)都是一件好事。我已经按照Google风格指南的几个部分进行了几年的跟踪。它与我的标准练习很容易合并。