今天仔细看了一下以前当参考书翻的《Effective C++》和《More Effective C++》,着重看了里面讲述关于操作符重载的种种实做方法,看着很爽,就自己实际操作了一遍。编译器使用VC++.NET 7.1,因为这个编译器对C++标准的支持达到99%。现在把测试代码和输出贴出来,供同志们交流之用。
//CInt.h///////////////////////////////////
#include <iostream>
using namespace std;
class CInt
{
public:
CInt();
CInt(int i);
CInt(CInt& cint);
CInt(CInt* pcint);
CInt& operator =(const CInt& i);
CInt& operator =(int i);
void operator <<(char *str);
friend CInt operator +(const CInt& lhv, const CInt& rhv);
~CInt();
private:
int m_i;
};
//CInt.cpp///////////////////////////////////
#include "CInt.h"
CInt::CInt() :m_i(0)
{
cout<<"\n CInt::CInt() this="<<this;
}
CInt::CInt(int i) :m_i(i)
{
cout<<"\n CInt::CInt(int i) m_i="<<m_i<<" this="<<this;
}
CInt::CInt(CInt &cint) :m_i(cint.m_i)
{
cout<<"\n CInt::CInt(CInt &cint) m_i="<<m_i<<" cint.m_i="<<cint.m_i<<" this="<<this<<" &cint="<<&cint;
}
CInt::CInt(CInt *pcint) :m_i(pcint->m_i)
{
cout<<"\n CInt::CInt(CInt *pcint) m_i="<<m_i<<" pcint->m_i="<<pcint->m_i<<" this="<<this<<" pcint="<<pcint;
}
CInt& CInt::operator =(const CInt &i)
{
cout<<"\n CInt::operator =(CInt &i) this="<<this<<" &i="<<&i;
m_i = i.m_i;
return (*this);
}
CInt& CInt::operator =(int i)
{
cout<<"\n CInt::operator =(int i) this=his="<<this<<" i="<<i;
m_i = i;
return (*this);
}
void CInt::operator <<(char *str)
{
cout<<"\n CInt::operator <<(char *str) this="<<this<<" m_i="<<m_i<<" "<<str;
}
CInt operator +(const CInt& lhv, const CInt& rhv)
{
cout<<"\n operator +(CInt& lhv, CInt& rhv) lhv="<<&lhv<<" rhv="<<&rhv;
return CInt(lhv.m_i+rhv.m_i);
}
CInt::~CInt()
{
cout<<"\n CInt::~CInt() this="<<this;
}
//main.cpp///////////////////////////////////
#include "CInt.h"
void Fun0(CInt i)
{
cout<<"\n Fun0(CInt i) &i="<<&i;
}
void Fun1(CInt &i)
{
cout<<"\n Fun1(CInt &i) &i="<<&i;
}
void Fun2(const CInt &i)
{
cout<<"\n Fun2(const CInt&i) &i="<<&i;
}
void main()
{
cout<<"CInt i(2), temp(10);";
CInt i(2), temp(10);
cout<<"\nCInt j(i);";
CInt j(i);
cout<<"\nCInt k(&i);";
CInt k(&i);
cout<<"\nFun0(i);";
Fun0(i);
cout<<"\nFun1(i);";
Fun1(i);
cout<<"\nFun2(2);";
Fun2(2);
cout<<"\ni = temp;";
i = temp;
cout<<"\ni = 20;";
i = 20;
cout<<"\ni<<\"mck\";";
i<<"mck";
cout<<"\ni = j+k;";
i = j+k;
cout<<"\ni = j+6;";
i = j+6;
cout<<"\ni = 5+j;";
i = 5+j;
cin.get();
}
/////////以下是输出/////////////////////////
CInt i(2), temp(10);
CInt::CInt(int i) m_i=2 this=0012FEC4
CInt::CInt(int i) m_i=10 this=0012FED4
CInt j(i);
CInt::CInt(CInt &cint) m_i=2 cint.m_i=2 this=0012FEC8 &cint=0012FEC4
CInt k(&i);
CInt::CInt(CInt *pcint) m_i=2 pcint->m_i=2 this=0012FED0 pcint=0012FEC4
Fun0(i);
CInt::CInt(CInt &cint) m_i=2 cint.m_i=2 this=0012FEBC &cint=0012FEC4
Fun0(CInt i) &i=0012FEBC
CInt::~CInt() this=0012FEBC
Fun1(i);
Fun1(CInt &i) &i=0012FEC4
Fun2(2);
CInt::CInt(int i) m_i=2 this=0012FECC
Fun2(const CInt&i) &i=0012FECC
CInt::~CInt() this=0012FECC
i = temp;
CInt::operator =(CInt &i) this=0012FEC4 &i=0012FED4
i = 20;
CInt::operator =(int i) this=his=0012FEC4 i=20
i<<"mck";
CInt::operator <<(char *str) this=0012FEC4 m_i=20 mck
i = j+k;
operator +(CInt& lhv, CInt& rhv) lhv=0012FEC8 rhv=0012FED0
CInt::CInt(int i) m_i=4 this=0012FECC
CInt::operator =(CInt &i) this=0012FEC4 &i=0012FECC
CInt::~CInt() this=0012FECC
i = j+6;
CInt::CInt(int i) m_i=6 this=0012FECC
operator +(CInt& lhv, CInt& rhv) lhv=0012FEC8 rhv=0012FECC
CInt::CInt(int i) m_i=8 this=0012FED8
CInt::operator =(CInt &i) this=0012FEC4 &i=0012FED8
CInt::~CInt() this=0012FED8
CInt::~CInt() this=0012FECC
i = 5+j;
CInt::CInt(int i) m_i=5 this=0012FECC
operator +(CInt& lhv, CInt& rhv) lhv=0012FECC rhv=0012FEC8
CInt::CInt(int i) m_i=7 this=0012FED8
CInt::operator =(CInt &i) this=0012FEC4 &i=0012FED8
CInt::~CInt() this=0012FED8
/////////测试总结/////////////////////////
首先是各操作符的参数类型均设置成了const常类型,这一点在More Effective C++一书条款19中有明确的说明,这样做是为了使操作符能接受隐式的类型转换参数。测试语句是main()中的Fun2(2)调用,输出为:
CInt::CInt(int i) m_i=2 this=0012FECC//隐式类型转换,由int 2构造临时对象
Fun2(const CInt&i) &i=0012FECC//临时对象的引用传递给Fun2
CInt::~CInt() this=0012FECC//Fun2结束,析构临时对象
根据这一点,在参数表中写上const将是一种是函数适用性提高的手段。
其次是operator + 的使用,这一点在Effctive C++条款19中有说明。若将该操作符声明为类的成员,则(CInt)i+(int)2的调用是正确的,而(int)2+(CInt)i的调用是错误的,这一点不满足内置类型int满足的交换率。因此操作符被声明为友元。测试语句是main()中的最后两句 i=j+6;i=5+j;输出为:
i = j+6;
CInt::CInt(int i) m_i=6 this=0012FECC//隐式类型转换,由int 6构造临时对象
operator +(CInt& lhv, CInt& rhv) lhv=0012FEC8 rhv=0012FECC//执行操作符制定的操作
CInt::CInt(int i) m_i=8 this=0012FED8//为了返回结果而构造另外一个局部无名对象
CInt::operator =(CInt &i) this=0012FEC4 &i=0012FED8//返回结果复制给i,所以调用“=”操作符
CInt::~CInt() this=0012FED8//释放局部无名对象
CInt::~CInt() this=0012FECC//操作符调用结束,释放临时对象
i = 5+j;//同上