• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

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

发布: 2007-7-01 20:40 | 作者: admin | 来源: | 查看: 11次 | 进入软件测试论坛讨论

领测软件测试网

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

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

为了使用一个已经实现了的一元运算符,如+,你可以把一个实现转换运算符把你的类型转换为已经实现了上述一元运算符的类型。例如,通过把你的类型转换为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 bSuccess = 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类。

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网