从赋值运算符的默认实现中获益(第二部分)

发表于:2007-07-01来源:作者:点击数: 标签:
在本文的第一部分,我们向你演示了如何从赋值与一元运算相结合的运算符(例如+=、又如*=等)的默认实现中获益。在这一部分,我们将向你演示如何轻松地创建with_default类以及这个类是如何从赋值运算符的默认实现中获益的。 with_default type [,defaultVal


在本文的第一部分,我们向你演示了如何从赋值与一元运算相结合的运算符(例如+=、又如*=等)的默认实现中获益。在这一部分,我们将向你演示如何轻松地创建with_default类以及这个类是如何从赋值运算符的默认实现中获益的。

with_default< type [,defaultValue]>类运用于将有内建类型(如int、long等等)地数据成员在其构造时赋给默认值。注意内建类型的默认构造函数并没有初始化变量。下面是一个例子:

struct Sum
{
Sum()
{ /*你并不知道变量‘m_nSumSoFar’的值是多少!!!*/ }
private:
int m_nSumSoFar;
}; 

在使用with_default类时,你要避免发生上面这样的错误。使用with_default< type [,defaultValue]>涉及到的语法很简单,如下所示

Type是你要给其赋值变量的类型。
DefaultValue是赋值给该变量的值(默认为‘type()’)。
下面是更正后的代码:

struct Sum
{
Sum()
{ /* 变量‘m_nSumSoFar’自动设置为0*/ }
private:
with_default&lt; int&gt; m_nSumSoFar;
}; 

现在,你应该认识到了with_default< type>的重要性,你可能也想如何把它用到你的项目上。为此,你需要运算符+=、-=等等。

下面是为with_default的代码和如何使用它的例子:

#include "operators.h"
#include &lt;iosfwd&gt;

// 前面的声明
template&lt; class type, type default_value = type() &gt;
struct with_default;

//……与基类一样有用
class no_op {};

template&lt; class type&gt; struct operations_for_type
{ typedef ops_all&lt; with_default&lt; type&gt;, type&gt; base_class; };

template&lt;&gt; struct operations_for_type&lt; void*&gt;
{ typedef no_op base_class; };

//……也许有一天VC将允许部分特殊化
#ifndef _MSC_VER
template&lt;class ptr&gt; struct operations_for_type&lt; ptr*&gt;
{ typedef ops_all_for_ptrs&lt; with_default&lt; ptr*&gt; &gt; base_class; };
#endif

template&lt; class type, type default_value = type() &gt;
struct with_default
: public operations_for_type&lt; type&gt;::base_class
{
with_default()
: m_value( default_value) {}
with_default( const type &amp; value)
: m_value( value) {}

operator const type () const
{ return m_value; }

with_default&lt; type, default_value&gt; &amp; operator=( type other)
{ m_value = other; return *this; }

// 只要这里有类型转化
// 这就要起作用
template&lt; class other_type, other_type other_default_value&gt;
with_default&lt; type, default_value&gt; &amp; operator=(
const with_default&lt; other_type, other_default_value&gt; &amp; other)
{ m_value = ( const other_type &amp;)other; return *this; }

private:
type m_value;
};

template&lt; class char_type, class char_traits, class type, type default_value&gt;
std::basic_istream&lt; char_type, char_traits&gt; &amp;
operator &gt;&gt;(
std::basic_istream&lt; char_type, char_traits&gt; &amp; streamIn,
with_default&lt; type, default_value&gt; &amp; value)
{ type read; streamIn &gt;&gt; read; value = read; return streamIn; }

/////////////////////////////////////////////////////
//例子

#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;

struct mul_sum_avg
{
void operator()( int value)
{
m_multiply *= value;
m_sum += value;
m_count++;
}
int mul() const { return m_multiply; }
int sum() const { return m_sum; }
//……处于举例的缘故,我们假设
// 至少有一个元素
int avg() const { return m_sum / m_count; }
private:
with_default&lt; int, 1&gt; m_multiply;
with_default&lt; int, 0&gt; m_sum;
with_default&lt; int, 0&gt; m_count;
};

int main(int argc, char* argv[])
{
int aVals[] = { 2, 4, 1, 9, 4, 2, 3};
int nCount = sizeof( aVals) / sizeof( aVals[ 0]);
mul_sum_avg result =
std::for_each( aVals, aVals + nCount, mul_sum_avg());
std::cout &lt;&lt; "mul= " &lt;&lt; result.mul() &lt;&lt; ", sum= " &lt;&lt; result.sum()
&lt;&lt; ", avg=" &lt;&lt; result.avg() &lt;&lt; std::endl ;
return 0;
}

原文转自:http://www.ltesting.net