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

发表于:2007-07-01来源:作者:点击数: 标签:
应用程序 开发 者优势需要使用一种数字式的类。当实现这样的数字式类时,你可能想重载运算符,如:+、-、*、/……等等,使得这些类在处理时,显得逻辑性强一些。 然而,一旦实现了运算符+,你可能又希望实现运算符+=,同样还有-、*、/、%、^、、|这些运


应用程序开发者优势需要使用一种数字式的类。当实现这样的数字式类时,你可能想重载运算符,如:+、-、*、/……等等,使得这些类在处理时,显得逻辑性强一些。

然而,一旦实现了运算符+,你可能又希望实现运算符+=,同样还有-、*、/、%、^、&、|这些运算符。

为了使用一个已经实现了的一元运算符,如+,你可以把一个实现转换运算符把你的类型转换为已经实现了上述一元运算符的类型。例如,通过把你的类型转换为int型,那么你就可以使用int型已经实现了的所有一元运算符。

所有的赋值运算符(除了=运算符)都可以继承。只要我们实现了一个一元运算符,如+,那么我们就可以产生该运算符对应于赋值运算的运算符,如+=。例如,a+=b等价于a=a+b。

所有的赋值运算符的默认实现都遵循下面的语法op_plus_equal< type, other_type = const type &>。其中,type是我们正在转换的赋值运算符,而other_type是第二参数的类型(例如,在a += b的情况下,other_type就是b的类型)。

提供的实现有:

op_plus_equal
op_minus_equal
op_multiply_equal
op_divide_equal
op_modulus_equal
op_xor_equal
op_and_equal
op_or_equal
ops_math_equal (+=,-=,*=,/=,%=)
ops_all_equal(+=,-=,*=,/=,%=,^=,|=,&=)
op_plus_plus (implementsx++/++x as x = x + 1)
op_minus_minus (implements x--/--x as x = x - 1)
ops_all (+=,-=,*=,/=,%=,^=,|=,&=,++,--)
ops_all_for_ptrs (+=,-=,++,--)
下面是赋值运算符的代码,然后是named_int例子:

#ifndef OPERATORS_H
#define OPERATORS_H

template&lt; class type, class other_type = const type &amp;&gt;
struct op_plus_equal
{
type &amp; operator +=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis + other;
return *pThis;
}
}; // +=
template&lt; class type, class other_type = const type &amp;&gt;
struct op_minus_equal
{
type &amp; operator -=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis - other;
return *pThis;
}
}; // -=
template&lt; class type, class other_type = const type &amp;&gt;
struct op_xor_equal
{
type &amp; operator ^=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis ^ other;
return *pThis;
}
}; // ^=
template&lt; class type, class other_type = const type &amp;&gt;
struct op_and_equal
{
type &amp; operator &amp;=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis &amp; other;
return *pThis;
}
}; // &amp;=
template&lt; class type, class other_type = const type &amp;&gt;
struct op_or_equal
{
type &amp; operator |=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis | other;
return *pThis;
}
}; // |=
template&lt; class type, class other_type = const type &amp;&gt;
struct op_multiply_equal
{
type &amp; operator *=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis * other;
return *pThis;
}
}; // *=
template&lt; class type, class other_type = const type &amp;&gt;
struct op_divide_equal
{
type &amp; operator /=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis / other;
return *pThis;
}
}; // /=
template&lt; class type, class other_type = const type &amp;&gt;
struct op_modulus_equal
{
type &amp; operator %=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis % other;
return *pThis;
}
}; // %=
template&lt; class type, class other_type = const type &amp;&gt;
struct ops_math_equal
: op_plus_equal&lt; type, other_type&gt;, op_minus_equal&lt; type, other_type&gt;,
op_multiply_equal&lt; type, other_type&gt;, op_divide_equal&lt; type, other_type&gt;,
op_modulus_equal&lt; type, other_type&gt;
{}; // math equal: +=, -=, *=, /=, %=
template&lt; class type, class other_type = const type &amp;&gt;
struct ops_all_equal
: op_plus_equal&lt; type, other_type&gt;, op_minus_equal&lt; type, other_type&gt;,
op_multiply_equal&lt; type, other_type&gt;, op_divide_equal&lt; type, other_type&gt;,
op_modulus_equal&lt; type, other_type&gt;, op_xor_equal&lt; type, other_type&gt;,
op_or_equal&lt; type, other_type&gt;, op_and_equal&lt; type, other_type&gt;
{}; // all equal: +=, -=, *=, /=, %=, ^=, |=, &amp;=
template&lt; class type, class other_type = int&gt;
struct op_plus_plus
{
type &amp; operator++()
{
type * pThis = ( type *)this;
*pThis = *pThis + other_type( 1);
return *pThis;
}
type operator++(int)
{
type * pThis = ( type *)this;
type tmp( *pThis);
*pThis = *pThis + other_type( 1);
return tmp;
}
}; // ++
template&lt; class type, class other_type = int&gt;
struct op_minus_minus
{
type &amp; operator--()
{
type * pThis = ( type *)this;
*pThis = *pThis - other_type( 1);
return *pThis;
}
type operator--(int)
{
type * pThis = ( type *)this;
type tmp( *pThis);
*pThis = *pThis - other_type( 1);
return tmp;
}
}; // --
template&lt; class type, class other_type = const type &amp;&gt;
struct ops_all
: public ops_all_equal&lt; type, other_type&gt;, public op_plus_plus&lt; type&gt;,
public op_minus_minus&lt; type&gt;
{}; // all: +=, -=, *=, /=, %=, ^=, |=, &amp;=, ++, --
// operations supported for pointers
template&lt; class type&gt;
struct ops_all_for_ptrs
: public op_plus_equal&lt; type, int&gt;, public op_minus_equal&lt; type, int&gt;,
public op_plus_plus&lt; type&gt;, public op_minus_minus&lt; type&gt;
{}; // all for pointers: +=, -=, ++, --
#endif // OPERATORS_H

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

#include &lt;string&gt;
#include &lt;iostream&gt;
#include "operators.h"

struct named_int
: public ops_all&lt; named_int, int&gt;
{
named_int( int value = 0, const std::string &amp; strName = std::string())
: m_value( value), m_strName( strName) {}
named_int( const std::string &amp; strName)
: m_value( 0), m_strName( strName) {}
operator const int () const
{ return m_value; }
named_int &amp; operator=( int other)
{ m_value = other; return *this; }
named_int &amp; operator=( const named_int &amp; other)
{ m_value = other.m_value; return *this; }

const std::string &amp; get_name() const
{ return m_strName; }
void set_name( const std::string &amp; strName)
{ m_strName = strName; }
private:
int m_value;
std::string m_strName;
};

std::istream &amp; operator&gt;&gt;( std::istream &amp; streamIn, named_int &amp; value)
{ int n; streamIn &gt;&gt; n; value = n; return streamIn; }

void read_and_validate( named_int &amp; n, int nLeast, int nMost)
{
std::cout &lt;&lt; "Enter " &lt;&lt; n.get_name() &lt;&lt; std::endl;
bool bSuclearcase/" target="_blank" >ccess = false;
while ( !bSuccess)
{
std::cin &gt;&gt; n;
bSuccess = ( n &gt;= nLeast) &amp;&amp; ( n &lt;= nMost);
if ( !bSuccess)
std::cout &lt;&lt; "nError! (valid values are between " &lt;&lt; nLeast
&lt;&lt; " and " &lt;&lt; nMost &lt;&lt; ") Try again!" &lt;&lt; std::endl;
}
}

int main(int argc, char* argv[])
{
named_int nDepartments( "No of Departments");
named_int nEmployees( "No Of Employees");
// reads the no. of departments; valid values are between 1 and 100
read_and_validate( nDepartments, 1, 100);
// reads the no. of employees; each departments
// can have at least 1 employee, at most 10 employees
read_and_validate( nEmployees, nDepartments, nDepartments * 10);
return 0;
}

在本文的第二部分,你将看到如何实现with_default类。

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