StupidBeauty
??Read times:31????Posted at:Wed Sep 27 01:19:55 2017?? - no title specified

《C++面向对象软件设计及构建》文章翻译:2.5默认参数,2.5 Default Arguments

默认参数,本身是正式参数,当调用者未提供实际的参数值的时候,会被自动赋予一个值(即为默认值)。当然,实际提供的参数值,如果存在的话,就会覆盖掉默认值。

以下这个基于Frame 类的示例,展示了默认参数的语法和用法。

class Frame {

private:

...

public:

...

void Resize (int width = 100, int height = 150);

...

};

在这个示例中,width 和height 参数都带有默认值。要体验默认值的效果的话,则观摩以下示例中对于Resize 方法的调用:

Frame window (100, 100, 300, 400);

...

window.Resize(200, 250);           // 情景1

window.Resize(200);                // 情景2

window.Resize();                   // 情景3

在第一种情景中,窗口的大小被改变为200 x 250:由于两个参数都正常提供了,所以默认值被忽略。在第二种情景中,Frame 对象的大小被改变为200 x 150:对于缺失的第二个(height)参数,使用了默认值150,而对于第一个(width)参数,则使用此处所提供的200 作为其值。第三种情景中,窗口的大小被改变为100 x 150,因为两个参数都是使用的默认值。

在构造函数中也可以使用默认参数值。例如,Frame 类,可重新定义如下:

class Frame {

private:

...

public:

Frame( char *name, int initXcoord =  50, int initYcoord =  50,

int initWidth  = 100, int initHeight = 100 );

...

};

这个唯一的构造函数,可按照以下不同方式使用:

Frame display1("Fully Specified", 200, 200, 300, 350);

Frame display2("No Height",      200, 200, 300);

Frame display3("Position Only",  200, 200);

Frame display4("No YCoordinate", 200)

Frame display5("Name Only");

Frame对象display1,被赋予了一个名字,会处于位置(200,200),其形状会是300 x 350。Frame对象display2,与display1 类似,区别就在于,它的高度是默认高度100,其值由initHeight 的默认值所指定。Frame对象display3,被赋予了一个名字,会处于位置(200,200),其形状会是100 x 100,形状由initWidth 和initHeight 的默认值确定。Frame对象display4,与display3 类似,区别只在于,它的名字不同,并且其位置是(200,50),此处的y坐标50,是由参数initYcoord 的默认值决定的。最后,是display5,它会有一个明确赋予的名字,而它的位置((50,50))和形状(100 x 100)则是由默认值决定。

注意,配合重载方法的使用,再加上默认参数的使用,就给予了方法的调用者以更多的灵活性,可以按照自己需要的方式来调用该方法。调用者只需要指定那些必要的参数,而让其它参数直接使用默认值。如果调用者需要更准确地控制方法中的参数的话,那么,也可以使用自己提供的值来覆盖掉默认值。

以下情况下可以使用默认值:

  • •.默认值可用来代替某个常见的值

  • •.作为一个“安全”值来使用,以确保做出有意义的计算

  • •.作为一个“无意义”(例如,超出范围)值来使用,使得被调用的方法使用某种算法来对此处缺失的参数值做出补偿

常见或安全默认值的例子包括:某个整数“计数器”,它的默认初始值是0;或者,某个字符串值,它的初始值是空白或是无效。设想Frame 类的某个变种,其中,x 坐标、y 坐标、高度和宽度的默认值都是-1,显然这些默认值是无意义的。Frame的构造函数,在遇到(部分的)这样的默认值的时候,就会使用某个内部算法,以确定,对于这些默认值,该使用一个什么样的合理的值。举个例子,在这种算法中,可能会尽量做到让本窗口与屏幕上其它窗口的重叠区域最小。

对于默认值的使用规则是:不带默认值的参数,不允许出现在带有默认值的参数之后(右边)。以下示例,展示了这条规则的必要性:

class Cube {

public:

...

Resize( int height = 10, int width = 20, int depth);

...

};

注意,这个示例,违反了前面所说的默认参数规则。因为,depth 参数没有默认值,而它却出现在拥有默认值的width 之后。再结合以下使用 Resize 方法的代码来看:

Cube cube;

...

cube.Resize(30, 50);

此处,对于Resize 的调用,可能会表示三种不同的意义:

cube.Resize(10, 30, 50);           // 使用height 的默认值

cube.Resize(30, 20, 50);           // 使用width 的默认值

cube.Resize(30, 50);               // 错误 - 不提供 depth参数

通过上面说的那条规则,就可以避免产生这种歧义,这对于编译器和程序猿来说都是好事。

任务

  1. 1. 对于之前 Frame ,编写 个带有默认参数值的构造函数,替换 掉之前写的4个重载的构造函数。

  2. 2. 利用默认参数 值为 Frame 编写一个MoveTo 方法定义。 对妳所选择的默认值进行解释及验证。

  3. 3. 利用默认参数 值为 Frame 编写一个Resize(int,int)方法定义。 对妳所选择的默认值进行解释及验证。

  4. 4. 利用默认参数 值为 Frame 编写一个Resize(float)方法定义。 对妳所选择的默认值进行解释及验证。

- no title specified

漂亮的笨蛋浏览器/2017.10.8/版本

 
??Like this article? Give us some tips.??