從賦值運算符的默認實現中獲益(第一部分)
發表于: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< class type, class other_type = const type &>
struct op_plus_equal
{
type & operator +=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis + other;
return *pThis;
}
}; // +=
template< class type, class other_type = const type &>
struct op_minus_equal
{
type & operator -=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis - other;
return *pThis;
}
}; // -=
template< class type, class other_type = const type &>
struct op_xor_equal
{
type & operator ^=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis ^ other;
return *pThis;
}
}; // ^=
template< class type, class other_type = const type &>
struct op_and_equal
{
type & operator &=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis & other;
return *pThis;
}
}; // &=
template< class type, class other_type = const type &>
struct op_or_equal
{
type & operator |=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis | other;
return *pThis;
}
}; // |=
template< class type, class other_type = const type &>
struct op_multiply_equal
{
type & operator *=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis * other;
return *pThis;
}
}; // *=
template< class type, class other_type = const type &>
struct op_divide_equal
{
type & operator /=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis / other;
return *pThis;
}
}; // /=
template< class type, class other_type = const type &>
struct op_modulus_equal
{
type & operator %=( other_type other)
{
type * pThis = ( type *)this;
*pThis = *pThis % other;
return *pThis;
}
}; // %=
template< class type, class other_type = const type &>
struct ops_math_equal
: op_plus_equal< type, other_type>, op_minus_equal< type, other_type>,
op_multiply_equal< type, other_type>, op_divide_equal< type, other_type>,
op_modulus_equal< type, other_type>
{}; // math equal: +=, -=, *=, /=, %=
template< class type, class other_type = const type &>
struct ops_all_equal
: op_plus_equal< type, other_type>, op_minus_equal< type, other_type>,
op_multiply_equal< type, other_type>, op_divide_equal< type, other_type>,
op_modulus_equal< type, other_type>, op_xor_equal< type, other_type>,
op_or_equal< type, other_type>, op_and_equal< type, other_type>
{}; // all equal: +=, -=, *=, /=, %=, ^=, |=, &=
template< class type, class other_type = int>
struct op_plus_plus
{
type & 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< class type, class other_type = int>
struct op_minus_minus
{
type & 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< class type, class other_type = const type &>
struct ops_all
: public ops_all_equal< type, other_type>, public op_plus_plus< type>,
public op_minus_minus< type>
{}; // all: +=, -=, *=, /=, %=, ^=, |=, &=, ++, --
// operations supported for pointers
template< class type>
struct ops_all_for_ptrs
: public op_plus_equal< type, int>, public op_minus_equal< type, int>,
public op_plus_plus< type>, public op_minus_minus< type>
{}; // all for pointers: +=, -=, ++, --
#endif // OPERATORS_H
/////////////////////////////////////////////////////////
//例子
#include <string>
#include <
iostream>
#include "operators.h"
struct named_int
: public ops_all< named_int, int>
{
named_int( int value = 0, const std::string & strName = std::string())
: m_value( value), m_strName( strName) {}
named_int( const std::string & strName)
: m_value( 0), m_strName( strName) {}
operator const int () const
{ return m_value; }
named_int & operator=( int other)
{ m_value = other; return *this; }
named_int & operator=( const named_int & other)
{ m_value = other.m_value; return *this; }
const std::string & get_name() const
{ return m_strName; }
void set_name( const std::string & strName)
{ m_strName = strName; }
private:
int m_value;
std::string m_strName;
};
std::istream & operator>>( std::istream & streamIn, named_int & value)
{ int n; streamIn >> n; value = n; return streamIn; }
void read_and_validate( named_int & n, int nLeast, int nMost)
{
std::cout << "Enter " << n.get_name() << std::endl;
bool bSu
clearcase/" target="_blank" >ccess = false;
while ( !bSuccess)
{
std::cin >> n;
bSuccess = ( n >= nLeast) && ( n <= nMost);
if ( !bSuccess)
std::cout << "nError! (valid values are between " << nLeast
<< " and " << nMost << ") Try again!" << 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.anti-gravitydesign.com