2011-01-21 52 views
3
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; 
} 

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

回答

4

如果有一个默认值可以在大量时间内提供正确的行为,那么它可以节省您编写不断传入相同值的代码。它只是让事情比写foo(SOME_DEFAULT)更简单。

+0

在这种情况下,在执行速度或存储器使用方面的任何优势? – 2011-01-21 03:45:52

+1

对!例如,检查Win32 API。在99%的情况下,你不需要其参数的一半。 – ruslik 2011-01-21 03:58:46

+0

天啊,这么多的空的,所以很多空的... ok_woei:老实说,我从来没有看着潜在的性能差异,但我非常,非常怀疑,如果有这将是微小的(但仍高度怀疑)。 – 2011-01-21 04:01:54

2

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

class Container 
{ 
    // ... 

    public: 

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

这使类的用户两者都做这样的:

Container MyContainer; // For clarity. 

这:

Container MyContainer(10); // For functionality. 
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; 
} 
5

您的添加函数并不是一个很好的示例,说明如何使用默认参数,并且您正确的使用默认参数更难以阅读。

但是,这不适用于所有功能。考虑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参数的构造即使是从来不需要它:调整为较小的尺寸时, 。因此,对于某些功能,过载比默认参数好。 (我会在此类别中包含vector :: resize。)例如,std :: getline以这种方式工作,但没有其他选择,因为第三个参数的“default”值是从第一个参数计算得出的。例如:

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++ 
2

埃德Swangren提到的,一些功能有这样的参数往往在大多数呼叫相同的值。在这些情况下,该值可以被指定为默认值。它还可以帮助您查看此参数的“建议”值。

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

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

此外,google's coding style建议避免它们。使用默认参数,正如其他人指出的

0

优势,不愧是“清晰度”它带来的代码相对于说函数重载。

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

塞班有一些很好的C++设计模式来避免这样的BC。

1

默认参数是具有提供给它的默认值的函数的参数。如果用户未提供此参数的值,则默认值将为 。如果用户确实提供了默认参数的值,则使用用户提供的值。 在计算机编程中,默认参数是程序员不需要指定的函数的参数。在大多数编程语言中,函数可能需要一个或多个参数。通常情况下,每一个参数必须全部指定(这是在C编程语言的情况下)