分享
 
 
 

Effective C++: Item 24

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

依myan文章中的网址,找到了些资料,故而贴出来,以方便大家!

Item 24: Choose carefully between function overloading and parameter defaulting.The confusion over function overloading and parameter defaulting stems from the fact that they both allow a single function name to be called in more than one way:

void f(); // f is overloaded

void f(int x);

f(); // calls f()

f(10); // calls f(int)

void g(int x = 0); // g has a default

// parameter value

g(); // calls g(0)

g(10); // calls g(10)

So which should be used when?

The answer depends on two other questions. First, is there a value you can use for a default? Second, how many algorithms do you want to use? In general, if you can choose a reasonable default value and you want to employ only a single algorithm, you'll use default parameters (see also Item 38). Otherwise you'll use function overloading.

Here's a function to compute the maximum of up to five ints. This function uses -- take a deep breath and steel yourself -- std::numeric_limits<int>::min() as a default parameter value. I'll have more to say about that in a moment, but first, here's the code:

int max(int a,

int b = std::numeric_limits<int>::min(),

int c = std::numeric_limits<int>::min(),

int d = std::numeric_limits<int>::min(),

int e = std::numeric_limits<int>::min())

{

int temp = a > b ? a : b;

temp = temp > c ? temp : c;

temp = temp > d ? temp : d;

return temp > e ? temp : e;

}

Now, calm yourself. std::numeric_limits<int>::min() is just the fancy new-fangled way the standard C++ library says what C says via the INT_MIN macro in <limits.h>: it's the minimum possible value for an int in whatever compiler happens to be processing your C++ source code. True, it's a deviation from the terseness for which C is renowned, but there's a method behind all those colons and other syntactic strychnine.

Suppose you'd like to write a function template taking any built-in numeric type as its parameter, and you'd like the functions generated from the template to print the minimum value representable by their instantiation type. Your template would look something like this:

template<class T>

void printMinimumValue()

{

cout << the minimum value representable by T;

}

This is a difficult function to write if all you have to work with is <limits.h> and <float.h>. You don't know what T is, so you don't know whether to print out INT_MIN or DBL_MIN or what.

To sidestep these difficulties, the standard C++ library (see Item 49) defines in the header <limits> a class template, numeric_limits, which itself defines several static member functions. Each function returns information about the type instantiating the template. That is, the functions in numeric_limits<int> return information about type int, the functions in numeric_limits<double> return information about type double, etc. Among the functions in numeric_limits is min. min returns the minimum representable value for the instantiating type, so numeric_limits<int>::min() returns the minimum representable integer value.

Given numeric_limits (which, like nearly everything in the standard library, is in namespace std -- see Item 28; numeric_limits itself is in the header <limits>), writing printMinimumValue is as easy as can be:

template<class T>

void printMinimumValue()

{

cout << std::numeric_limits<T>::min();

}

This numeric_limits-based approach to specifying type-dependent constants may look expensive, but in fact it's not. That's because the long-windedness of the source code fails to be reflected in the resultant object code. In fact, calls to functions in numeric_limits generate no instructions at all. To see how that can be, consider the following, which is an obvious way to implement numeric_limits<int>::min:

#include <limits.h>

namespace std {

inline int numeric_limits<int>::min() throw ()

{ return INT_MIN; }

}

Because this function is declared inline, calls to it should be replaced by its body (see Item 33). That's just INT_MIN, which is itself a simple #define for some implementation-defined constant. So even though the max function at the beginning of this Item looks like it's making a function call for each default parameter value, it's just using a clever way of referring to a type-dependent constant, in this case the value of INT_MIN. Such efficient cleverness abounds in C++'s standard library. You really should read Item 49.

Getting back to the max function, the crucial observation is that max uses the same (rather inefficient) algorithm to compute its result, regardless of the number of arguments provided by the caller. Nowhere in the function do you attempt to figure out which parameters are "real" and which are defaults. Instead, you have chosen a default value that cannot possibly affect the validity of the computation for the algorithm you're using. That's what makes the use of default parameter values a viable solution.

For many functions, there is no reasonable default value. For example, suppose you want to write a function to compute the average of up to five ints. You can't use default parameter values here, because the result of the function is dependent on the number of parameters passed in: if 3 values are passed in, you'll divide their sum by 3; if 5 values are passed in, you'll divide their sum by 5. Furthermore, there is no "magic number" you can use as a default to indicate that a parameter wasn't actually provided by the client, because all possible ints are valid values for the parameters. In this case, you have no choice: you must use overloaded functions:

int avg(int a);

int avg(int a, int b);

int avg(int a, int b, int c);

int avg(int a, int b, int c, int d);

int avg(int a, int b, int c, int d, int e);

The other case in which you need to use overloaded functions occurs when you want to accomplish a particular task, but the algorithm that you use depends on the inputs that are given. This is commonly the case with constructors: a default constructor will construct an object from scratch, whereas a copy constructor will construct one from an existing object:

// A class for representing natural numbers

class Natural {

public:

Natural(int initValue);

Natural(const Natural& rhs);

private:

unsigned int value;

void init(int initValue);

void error(const string& msg);

};

inline void Natural::init(int initValue) { value = initValue; }

Natural::Natural(int initValue)

{

if (initValue > 0) init(initValue);

else error("Illegal initial value");

}

inline Natural::Natural(const Natural& x)

{ init(x.value); }

The constructor taking an int has to perform error checking, but the copy constructor doesn't, so two different functions are needed. That means overloading. However, note that both functions must assign an initial value for the new object. This could lead to code duplication in the two constructors, so you maneuver around that problem by writing a private member function init that contains the code common to the two constructors. This tactic -- using overloaded functions that call a common underlying function for some of their work -- is worth remembering, because it's frequently useful (see e.g., Item 12).

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有