C/C++样式--修改函数参数

C/C++ style -- modifying function arguments

本文关键字:修改 函数 参数 样式 C++      更新时间:2023-10-16

每个人都知道C/C++函数参数是按值传递的。那么,为什么有些人坚持认为正确的风格是在修改函数参数之前先对其进行本地复制呢?例如,他们会写:

void baz(unsigned int *ptr)
{
  unsigned int *lPtr = ptr;
  for(int i = 0; i < 10; i++)
  {
      foo(*lPtr++);
  }
}

而不是:

void baz(unsigned int *ptr)
{
  for(int i = 0; i < 10; i++)
  {
      foo(*ptr++);
  }
}

第二种方式似乎更容易阅读,因为它少了一个变量。

唯一的理由是对于更大的函数,有人可能会在函数底部添加新功能,而没有意识到参数早些时候被修改或无效。

想象一下:

int bighorriblefunction(const char * astr)
{
  // hundreds of lines of horribleness
  while ( * astr ) { /* something */  ++ astr ; }
  // more pages of code
  /** author two adds later */
  if ( ! strcmp(astr, "magicvalue") ) { /** do this really important thing **/  return 1 ; }
  return 0 ;
}

两位作者需要一段时间才能意识到新代码永远不会运行。

他们这样做是因为原始值在调试时很有用。

我认为这是因为代码的作者在baz()的第一个版本中编写了变量的声明,然后他重构了代码,这将for循环中的代码移动到了函数foo()中,而作者错误地没有删除变量。变量是纯粹的浪费。希望这能有所帮助!

这是接口与实现分离的拙劣版本。

假设你一年前写了这个代码:

class Foo
{
public:
    void bar( const char *where )
    {
        // The dreaded copy
        const char *destination = where;
        // The actual implementation that in the real world may take 500 
        // lines of code with 20 references to the variable destination
    }
};

现在,一年后,您希望使参数(其中是可选的)默认为类的成员变量。唉,你不记得那500行代码到底是干什么的了!幸运的是,您可以通过在使用前复制的参数来保存:

class Foo
{
public:
    void bar( const char *where = NULL)
    {
        // Hooray! I only have to change 1 line here!
        const char *destination = where? where : m_MyHomeDir.c_str();
        // The actual implementation that in the real world may take 500 
        // lines of code with 20 references to the variable destination
    }
private:
    std::string m_MyHomeDir;
};

如果你在C++中进行,只需使用:

std::for_each(ptr, ptr+10, foo);

我知道,这并不能直接回答这个问题,但确实指向了一个事实,即它通常应该是无关紧要的。如果它是相关的,那么您可能需要重写代码。

我不清楚这些"某些人"是谁(我从来没有听说过这种需求),但我能想到的唯一合理的原因是它稍微有助于调试:如果调试器在中间停止函数,你可以看到它最初被调用的参数值。然而,在大多数情况下,只需向上移动一个调用帧并查看传递给函数的表达式的值,就可以实现同样的效果。