使用默认功能参数的优点

时间:2011-01-21 03:29:31

标签: c++

int add (int x, int y=1)
int main ()
{
  int result1 = add(5);
  int result2 = add(5, 3);
  result 0;
}

VS

int add (int x, int y)
int main ()
{
  int result1 = add(5, 1);
  int result2 = add(5, 3);
  result 0;
}

在执行速度,内存使用等方面,使用默认函数参数有什么好处?对于像我这样的初学者,在我意识到使用默认函数参数之前,我有时会感到困惑;是不是没有默认功能参数编码使代码更容易阅读?

8 个答案:

答案 0 :(得分:6)

你的添加功能不是如何使用默认参数的一个很好的例子,你是正确的,一个更难阅读。

但是,并非所有功能都适用。考虑一下std :: vector :: resize,它看起来像:

template<class T>
struct vector_imitation {
  void resize(int new_size, T new_values=T());
};

这里,在不提供值的情况下调整大小使用T()。这是一个非常常见的情况,我相信几乎每个人都发现调整大小的单参数调用很容易理解:

vector_imitation<int> v;  // [] (v is empty)
v.resize(3);              // [0, 0, 0] (since int() == 0)
v.resize(5, 42);          // [0, 0, 0, 42, 42]

即使从不需要new_value参数,也会构建new_value参数:调整为较小的大小时。因此,对于某些功能,过载比默认参数更好。 (我将在此类别中包含vector :: resize。)例如,std :: getline以这种方式工作,但它没有其他选择,因为第三个参数的“默认”值是从第一个参数计算的。类似的东西:

template<class Stream, class String, class Delim>
Stream& getline_imitation(Stream &in, String &out, Delim delim);

template<class Stream, class String>
Stream& getline_imitation(Stream &in, String &out) {
  return getline_imitation(in, out, in.widen('\n'));
}

如果可以为函数提供命名参数,则默认参数会更有用,但C ++并不能简化这一过程。如果您在其他语言中遇到默认参数,则需要记住此C ++限制。例如,想象一个函数:

void f(int a=1, int b=2);

如果您还为所有后续参数使用给定的默认值,而不是能够调用,则只能使用参数的给定默认值,例如:

f(b=42)  // hypothetical equivalent to f(a=1, b=42), but not valid C++

答案 1 :(得分:4)

如果有一个默认值会在很长一段时间内提供正确的行为,那么它可以节省您编写不断传递相同值的代码。它只是比在整个地方编写foo(SOME_DEFAULT)更简单。

答案 2 :(得分:2)

它有广泛的用途。我通常在类构造函数中使用它们:

class Container
{
    // ...

    public:

    Container(const unsigned int InitialSize = 0)
    {
        // ...
    }
};

这使得该类的用户可以执行以下操作:

Container MyContainer; // For clarity.

而且:

Container MyContainer(10); // For functionality.

答案 3 :(得分:2)

喜欢它所依赖的一切。

您可以使用它来使代码更清晰。

void doSomething(int timeout=10)
{
    // do some task with a timeout, if not specified use a reasonable default
}

比在整个代码中有很多神奇的值doSomething(10)

更好

但要小心使用它,你应该真正做功能重载。

int add(int a) 
{ 
    return a+1; 
}

int add(int a,int b) 
{ 
    return a+b; 
}

答案 4 :(得分:2)

正如Ed Swangren所提到的,某些函数具有在大多数调用中具有相同值的参数。在这些情况下,可以将此值指定为默认值。它还可以帮助您查看此参数的“建议”值。

其他有用的情况是refractoring,当你为函数添加一些功能和参数,并且不想破坏旧代码时。例如,strlen(const char* s)计算到字符串中第一个\0字符的距离。您可能需要查找另一个被分类的内容,以便您编写更通用的版本:strlen(const char* s, char c='\0')。这将重用旧strlen的代码,而不会破坏与旧代码的兼容性。

默认值的主要问题是,当您查看或使用其他人编写的代码时,您可能不会注意到此隐藏参数,因此您不会知道该函数比您从代码中看到的更强大。

此外,google's coding style建议避免使用它们。

答案 5 :(得分:1)

默认参数是一个提供默认值的函数参数。如果用户未提供此参数的值,则默认值为 用过的。如果用户确实为默认参数提供值,则使用用户提供的值。 在计算机编程中,默认参数是程序员不需要指定的函数的参数。在大多数编程语言中,函数可以采用一个或多个参数。通常,每个参数必须完整指定(这是C编程语言中的情况)

答案 6 :(得分:0)

正如其他人所指出的那样,使用默认参数的优点确实是代码中关于函数重载的“清晰度”。

但是,重要的是要记住使用该语言的编译时功能的主要缺点:二进制兼容性和默认函数参数不是齐头并进的。 因此,最好避免在API /接口类中使用默认参数。因为,每次将默认参数更改为其他内容时,您的客户端都需要重新编译并重新链接。

Symbian有一些非常好的C ++设计模式来避免这种BC。

答案 7 :(得分:0)

最好避免使用默认参数。

让我们考虑以下示例

int DoThis(int a, int b = 5, int c = 6) {}

现在可以说您正在多个地方使用它

Place 1: DoThis(1);
Place 2: DoThis(1,2);
Place 3: DoThis(1,2,3);

现在您想向该功能添加1个参数,这是必填字段(该功能的扩展功能)。

int DoThis(int a, int x, int b =5, int c=6)

您的编译器仅对“位置1”抛出错误。您解决了。那其他人呢?

想象一下在一个大型项目中会发生什么?识别其用法并正确更新将成为一场噩梦。

总是超载:

int DoThis(int a) {}
int DoThis(int a, int b {}
int DoThis(int a, int b, int c) {}
int DoThis(int a, int b, int c, int x) {}