运算符重载
真的是过了许久,不想动数电实验,就来补一下blog,惭愧至极,已经遗忘了这部分的内容,暂且先存下来,债之后再补。
一(DoubleSubscriptedArray类)
问题描述
(Overloading the Parentheses Operator)One nice example of overloading the function call operator () is to allow another form of double-array subscripting popular in some programming languages.
Instead of saying chessBoard[ row ][ column ] for an array of objects, overload the function call operator to allow the alternate form chessBoard( row, column) Create a class DoubleSubscriptedArray that has similar features to class Array in Figs. 11.10–11.11. At construction time, the class should be able to create an array of any number of rows and any number of columns. The class should supply operator() to perform double-subscripting operations.
For example, in a 3-by-5 DoubleSubscriptedArray called a, the user could write a(1,3) to access the element at row 1 and column 3. Remember that operator() can receive any number of arguments. The underlying representation of the double-subscripted array should be a single-subscripted array of integers with rows * columns number of elements. Function operator() should perform the proper pointer arithmetic to access each element of the array. There should be
two versions of operator()—one that returns int & (so that an element of a DoubleSubscriptedArray canbe used as an lvalue) and one that returns const int & . The class should also provide the following operators: ==, !=, =,<< (for outputting the array in row and column format) and >> (for inputting the entire array contents).
实验提示
1)类定义示例:
class DoubleSubscriptedArray
{
friend ostream &operator<<(
ostream &, const DoubleSubscriptedArray & );
friend istream &operator>>(
istream &, DoubleSubscriptedArray & );
public:
DoubleSubscriptedArray( int = 3, int = 3 ); // default constructor
// copy constructor
DoubleSubscriptedArray( const DoubleSubscriptedArray & );
~DoubleSubscriptedArray(); // destructor
int getRowSize() const;// return number of rows
int getColumnSize() const;// return number of columns
const DoubleSubscriptedArray &operator=(
const DoubleSubscriptedArray & );
// assignment operator
// equality operator
bool operator==( const DoubleSubscriptedArray & ) const;
// inequality operator; returns opposite of == operator
bool operator!=( const DoubleSubscriptedArray &right ) const
{
return !( *this ==right );
} // end function operator!=
// function call operator for non-const objects
// returns modifiable lvalue
int &operator()( int, int );
// function call operator for const objects returns rvalue
int operator()( int, int ) const;
private:
int rowSize; // number of rows in array
int columnSize; // number of columns in array
int *ptr; // pointer to first element of pointer-based array
}; // end class DoubleSubscriptedArray
#endif
2)测试函数示例
#include <iostream>
#include "DoubleSubscriptedArray.h"
using namespace std;
int main()
{
DoubleSubscriptedArray integers1( 2, 4 ); //seven-element array
DoubleSubscriptedArray integers2; // 3-by-3 array by default
// print integers1 size and contents
cout << "Size of DoubleSubscriptedArray integers1 is "
<<integers1.getRowSize() << " X "<< integers1.getColumnSize()
<< "\nDoubleSubscriptedArray after initialization:\n" << integers1;
// print integers2 size and contents
cout << "\nSize of DoubleSubscriptedArray integers2 is"
<<integers2.getRowSize() << " X "<< integers2.getColumnSize()
<< "\nDoubleSubscriptedArray after initialization:\n" << integers2;
// input and print integers1 and integers2
cout << "\nEnter 17 integers:" << endl;
cin >>integers1 >> integers2;
cout << "\nAfter input, the DoubleSubscriptedArrays contain:\n"
<< "integers1:\n" << integers1<< "\nintegers2:\n" << integers2<< endl;
// use overloaded inequality (!=) operator
cout << "Evaluating: integers1 != integers2"<< endl;
if ( integers1 != integers2 )
cout << "integers1 and integers2 are not equal"<< endl;// create DoubleSubscriptedArray integers3 using integers1 as an// initializer with copy constructor; print size and contents
DoubleSubscriptedArray integers3( integers1 );
cout << "\nSize of DoubleSubscriptedArray integers3 is"
<<integers3.getRowSize() << " X "
<<integers3.getColumnSize()
<< "\nDoubleSubscriptedArray after initialization:\n" << integers3;
// use overloaded assignment (=) operator
cout << "\nAssigning integers2 to integers1:"<< endl;
integers1 =integers2; // note target Array is smaller
cout << "integers1:\n" << integers1 << "\nintegers2:\n"<< integers2;
//use overloaded equality (==) operator
cout << "\nEvaluating: integers1 == integers2"<< endl;
if ( integers1 == integers2 )
cout << "integers1 and integers2 are equal"<< endl; // use overloaded subscript operator to create rvalue
cout << "\nintegers1( 1, 2 ) is " <<integers1( 1, 2 );
// use overloaded subscript operator to create lvalue
cout << "\n\nAssigning 1000 to integers1( 1, 2 )"<< endl;
integers1( 1, 2 ) =1000;
cout << "integers1:\n" << integers1;// attempt to use out-of-range subscript
cout << "\nAttempt to assign 1000 to integers1( 15, 2)" << endl;
integers1( 15, 2 ) =1000; // ERROR: out of range
} // end main
【我的代码】
//DoubleSubscriptedArray.h
#include<iostream>
using namespce std;
#ifndef DOUBLESUBSCRIPTEDARRAY_H
#define DOUBLESUBSCRIPTEDARRAY_H
class DoubleSubscriptedArray
{
friend ostream &operator<<(ostream &,const DoubleSubscriptedArray &);
friend istream &operator>>(istream &,DoubleSubscriptedArray &);
public:
DoubleSubscriptedArray(int = 3,int = 3); //default constructor
DoubleSubscriptedArray(const DoubleSubscriptedArray &);//copy constructor
~DoubleSubscriptedArray(); // destructor
int getRowSize() const;
int getColumnSize() const;
const DoubleSubscriptedArray &operator=(const DoubleSubscriptedArray & ); // assignment operator
bool operator==( const DoubleSubscriptedArray & ) const;
bool operator!=( const DoubleSubscriptedArray &right ) const
{
return !( *this == right );
}
int &operator()(int,int);
int operator()(int,int) const;
private:
int rowSize;
int columnSize;
int *ptr;
};
#endif
//DoubleSubscriptedArray.cpp
#include<iostream>
#include<iomanip>
#include"DoubleSubscriptedArray.h"
using namespace std;
istream &operator>>(istream &input,DoubleSubscriptedArray &a)
{
for(int i=0;i<a.rowSize;i++)
for(int j=0;j<a.columnSize;j++)
input>>a.ptr[i*a.columnSize+j];
return input;
}
ostream &operator<<(ostream &output,const DoubleSubscriptedArray &a)
{
for(int i=0;i<a.rowSize;i++)
{
for(int j=0;j<a.columnSize;j++)
output<<setw(5)<<a.ptr[i*a.columnSize+j];
output<<endl;
}
return output;
}
DoubleSubscriptedArray::DoubleSubscriptedArray(int r,int c)
{
rowSize=r;
columnSize=c;
ptr=new int[rowSize*columnSize];
for(int i=0;i<rowSize;i++)
for(int j=0;j<columnSize;j++)
ptr[i*columnSize+j]=0;
}
DoubleSubscriptedArray::DoubleSubscriptedArray(const DoubleSubscriptedArray &A)
{
rowSize=A.rowSize;
columnSize=A.columnSize;
ptr=new int[rowSize*columnSize];
for(int i=0;i<rowSize;i++)
for(int j=0;j<columnSize;j++)
ptr[i*columnSize+j]=A.ptr[i*columnSize+j];
}
DoubleSubscriptedArray::~DoubleSubscriptedArray()
{
delete []ptr;//非常重要
}
int DoubleSubscriptedArray::getRowSize() const
{
return rowSize;
}
int DoubleSubscriptedArray::getColumnSize() const
{
return columnSize;
}
const DoubleSubscriptedArray &DoubleSubscriptedArray::operator=(const DoubleSubscriptedArray &right)
{
if(&right !=this)//避免自我赋值
{
if(rowSize!=right.rowSize||columnSize!=right.columnSize)
{
delete []ptr;
rowSize=right.rowSize;
columnSize=right.columnSize;
ptr=new int[rowSize*columnSize];
}
for(int i=0;i<rowSize;i++)
for(int j=0;j<columnSize;j++)
ptr[i*columnSize+j]=right.ptr[i*columnSize+j];
}
return *this;
}// assignment operator
bool DoubleSubscriptedArray::operator==(const DoubleSubscriptedArray &a) const
{
if(columnSize!=a.columnSize||rowSize!=a.rowSize)
return false;
else
{
for(int i=0;i<rowSize;i++)
for(int j=0;j<columnSize;j++)
{
if(ptr[i*columnSize+j]!=a.ptr[i*columnSize+j])
return false;
}
}
return true;
}
int &DoubleSubscriptedArray::operator()(int row,int column)
{
if(row<0||row>=rowSize)
{
cout<<"Error: row "<<row<<" out of range"<<endl;
}
if(column<0||column>=columnSize)
{
cout<<"Error: column "<<column<<" out of range"<<endl;
}
return ptr[row*columnSize+column];
}
int DoubleSubscriptedArray::operator()(int row,int column) const
{
if(row<0||row>=rowSize)
{
cout<<"Error: row "<<row<<" out of range"<<endl;
}
if(column<0||column>=columnSize)
{
cout<<"Error: column "<<column<<" out of range"<<endl;
}
return ptr[row*columnSize+column];
}
//DoubleSubscriptedArray类.cpp
#include <iostream>
#include "DoubleSubscriptedArray.h"
using namespace std;
int main()
{
DoubleSubscriptedArray integers1(2,4);
DoubleSubscriptedArray integers2;
cout << "Size of DoubleSubscriptedArray integers1 is "
<<integers1.getRowSize()<< " X " <<integers1.getColumnSize()
<<"\nDoubleSubscriptedArray after initialization:\n" << integers1;
cout << "\nSize of DoubleSubscriptedArray integers2 is "
<< integers2.getRowSize() << " X " << integers2.getColumnSize()
<< "\nDoubleSubscriptedArray after initialization:\n" << integers2;
cout << "\nEnter 17 integers:" << endl;
cin >> integers1 >> integers2;// >>级联调用
cout << "\nAfter input, the DoubleSubscriptedArrays contain:\n"
<< "integers1:\n" << integers1
<< "\nintegers2:\n" << integers2 << endl;
cout << "Evaluating: integers1 != integers2" << endl;
if ( integers1 != integers2 )
cout << "integers1 and integers2 are not equal" << endl;
DoubleSubscriptedArray integers3( integers1 );
cout << "\nSize of DoubleSubscriptedArray integers3 is "
<< integers3.getRowSize() << " X " << integers3.getColumnSize()
<< "\nDoubleSubscriptedArray after initialization:\n" << integers3;
cout << "\nAssigning integers2 to integers1:" << endl;
integers1 = integers2; // note target Array is smaller
cout << "integers1:\n" << integers1 << "\nintegers2:\n" << integers2;
cout << "\nEvaluating: integers1 == integers2" << endl;
if ( integers1 == integers2 )
cout << "integers1 and integers2 are equal" << endl;
// use overloaded subscript operator to create rvalue
cout << "\nintegers1( 1, 2 ) is " << integers1( 1, 2 );
// use overloaded subscript operator to create lvalue
cout << "\n\nAssigning 1000 to integers1( 1, 2 )" << endl;
integers1( 1, 2 ) = 1000;//非常成员函数
cout << "integers1:\n" << integers1;
/ attempt to use out-of-range subscript
cout << "\nAttempt to assign 1000 to integers1( 15, 2 )" << endl;
integers1( 15, 2 ) = 1000; // ERROR: out of range
system("pause");
return 0;
}
二(Hugeint类)
问题描述类定义参考
#ifndef HUGEINT_H
#define HUGEINT_H
#include<iostream>
using std::ostream;
class HugeInt
{
friend ostream &operator<<(ostream &, const HugeInt & );
public:
HugeInt( long = 0 ); // conversion/default constructor
HugeInt( const char * ); // conversion constructor
// addition operator; HugeInt + HugeInt
HugeInt operator+( const HugeInt & )const;
// addition operator; HugeInt + int
HugeInt operator+( int ) const;
// addition operator;
// HugeInt + string that represents largeinteger value
HugeInt operator+( const char * ) const;
bool operator==( const HugeInt & )const; // equality operator
bool operator!=( const HugeInt & )const; // inequality operator
bool operator<( const HugeInt & )const; // less than operator
bool operator<=( const HugeInt & )const; // less than or equal to operator
bool operator>( const HugeInt & )const; // greater than operator
bool operator>=( const HugeInt & )const;//greater than or equal to operator
HugeInt operator-( const HugeInt & )const; // subtraction operator
HugeInt operator*( const HugeInt & )const; // multiply two HugeInts
HugeInt operator/( const HugeInt & )const; // divide two HugeInts
int getLength() const;
private:
short integer[ 30 ];
}; // end class HugeInt
#endif
结果输出示例
【我的代码】
\\Hugeint.h
#include <iostream>
using std::ostream;
#ifndef HUGEINT_H
#define HUGEINT_H
class HugeInt
{
friend ostream &operator<<( ostream &, const HugeInt & );
public:
HugeInt( int = 0 ); // conversion/default constructor
HugeInt( const char * ); // conversion constructor
HugeInt operator+( const HugeInt & ) ;
HugeInt operator+( int ) ;
HugeInt operator+( const char * ) ;
bool operator==( const HugeInt & ) const;
bool operator!=( const HugeInt & ) const;
bool operator<( const HugeInt & ) const;
bool operator<=( const HugeInt & ) const;
bool operator>( const HugeInt & ) const;
bool operator>=( const HugeInt & ) const;
HugeInt operator-( const HugeInt & ) ;
HugeInt operator*( const HugeInt & ) ;
HugeInt operator/( const HugeInt & ) ;
int getLength() const;
private:
short integer[ 30 ];
};
#endif
\\Hugeint.cpp
#include<iostream>
#include<cstring>
#include<iomanip>
#include"Hugeint.h"
using namespace std;
HugeInt::HugeInt(int a)
{
int i;
for(i=1;i<30&&a!=0;i++)
{
integer[i]=a%10;
a/=10;
}
integer[0]=i-1;
for(int j=i;j<30;j++)
integer[j]=0;
}
HugeInt::HugeInt(const char *a)
{
integer[0]=((a=='\0') ?0:strlen(a));
for(int i=0;i<integer[0];i++)
integer[integer[0]-i]=a[i]-48;
for(int i=integer[0]+1;i<30;i++)
integer[i]=0;
}
HugeInt HugeInt::operator+( const HugeInt &a )
{
HugeInt temp;
temp.integer[0]=((integer[0]>a.integer[0])?integer[0]:a.integer[0]);
for(int i=1;i<temp.integer[0];i++)
{
temp.integer[i]+=integer[i]+a.integer[i];
if(temp.integer[i]>=10)
{
temp.integer[i]%=10;
temp.integer[i+1]++;
}
}
temp.integer[temp.integer[0]]+=integer[temp.integer[0]]+a.integer[temp.integer[0]];
if(temp.integer[temp.integer[0]]>=10&&temp.integer[0]<29)
{
temp.integer[temp.integer[0]]%=10;
temp.integer[temp.integer[0]+1]++;
temp.integer[0]++;
}
return temp;
}
HugeInt HugeInt::operator+( int a)
{
HugeInt temp(a);
HugeInt tempInt;
tempInt=*this+temp;
return tempInt;
}
HugeInt HugeInt::operator+(const char *a )
{
HugeInt temp(a);
HugeInt tempInt;
tempInt=*this+temp;
return tempInt;
}
bool HugeInt::operator==( const HugeInt &a ) const
{
if(integer[0]!=a.integer[0])
return false;
for(int i=1;i<=integer[0];i++)
if(integer[i]!=a.integer[i])
return false;
return true;
}
bool HugeInt::operator!=( const HugeInt & right) const
{
return !(*this==right);
}
bool HugeInt::operator<( const HugeInt &a ) const
{
if(integer[0]>a.integer[0])
return false;
if(integer[0]<a.integer[0])
return true;
else
{
for(int i=integer[0];i>0;i--)
{
if(integer[i]<a.integer[i])
return true;
if(integer[i]>a.integer[i])
return false;
}
return false;
}
}
bool HugeInt::operator<=( const HugeInt &right ) const
{
return !(right<*this);
}
bool HugeInt::operator>( const HugeInt & right) const
{
return right<*this;
}
bool HugeInt::operator>=( const HugeInt & right) const
{
return !(*this<right);
}
HugeInt HugeInt::operator-( const HugeInt &a )//默认被减数大于等于减数
{
HugeInt temp;
temp.integer[0]=integer[0];
int i;
for(i=1;i<integer[0];i++)
{
temp.integer[i]+=integer[i]-a.integer[i];
if(temp.integer[i]<0)
{
temp.integer[i]+=10;
temp.integer[i+1]--;
}
}
temp.integer[i]+=integer[i]-a.integer[i];
while(temp.integer[i]==0&&i>1)
{
temp.integer[0]--;
i--;
}
return temp;
}
HugeInt HugeInt::operator*( const HugeInt &a )
{
HugeInt temp;
int p=1;
for(int i=1;i<=a.integer[0];i++)
{
for(int j=0;j<a.integer[i]*p;j++)
temp=temp+*this;
p*=10;
}
temp.integer[0]=integer[0]+a.integer[0];
while(temp.integer[temp.integer[0]]==0&&temp.integer[0]>1)
temp.integer[0]--;
return temp;
}
/*HugeInt HugeInt::operator*(const HugeInt &a)
{
HugeInt temp;
int x;
for(int i=1;i<=integer[0];i++)
{
x=0;
for(int j=1;j<=a.integer[0];j++)
{
temp.integer[i+j-1]+=integer[i]*a.integer[j]+x;
x=temp.integer[i+j-1]/10;
temp.integer[i+j-1]%=10;
}
temp.integer[i+a.integer[0]]=x;
}
temp.integer[0]=integer[0]+a.integer[0];
while(temp.integer[temp.integer[0]]==0&&temp.integer[0]>1)
temp.integer[0]--;
return temp;
}*/
HugeInt HugeInt::operator/( const HugeInt &a )
{
int k=0;
HugeInt temp;
HugeInt tempInt1(*this);
while(tempInt1>=a)
{
tempInt1=tempInt1-a;
k++;
}
temp=temp+k;
return temp;
}
int HugeInt::getLength() const
{
return integer[0];
}
ostream &operator<<(ostream &output,const HugeInt &a)
{
if(a.integer[0]==0)
output<<0;
else
{
for(int i=1;i<=a.integer[0];i++)
output<<a.integer[a.integer[0]-i+1];
}
return output;
}
\\Hugeint类.cpp
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cmath>
#include"Hugeint.h"
using namespace std;
int main()
{
HugeInt n1("7654321");
HugeInt n2("7891234");
HugeInt n3("99999999999999999999999999999");
HugeInt n4("1");
HugeInt n5("12341234");
HugeInt n6("7888");
HugeInt result;
cout<<"n1 is "<<n1<<endl<<"n2 is "<<n2<<endl
<<"n3 is "<<n3<<endl<<"n4 is "<<n4<<endl
<<"n5 is "<<n5<<endl<<"n6 is "<<n6<<endl
<<"result is "<<result<<"\n\n";
if(n1!=n2)
cout<<"n1 is not equal to n2"<<endl;
if(n1<n2)
cout<<"n1 is less than n2"<<endl;
if(n1<=n2)
cout<<"n1 is less than or equal to n2"<<endl;
cout<<n1<<" + "<<n2<<" = "<<n1+n2<<"\n\n";
cout<<n3<<" + "<<n4<<" = "<<n3+n4<<"\n\n";
cout<<n1<<" + 9 = "<<n1+9<<endl;
cout<<n2<<" + 10000 = "<<n2+10000<<endl;
cout<<n5<<" * "<<n6<<" = "<<n5*n6<<endl;
cout<<n5<<" - "<<n6<<" = "<<n5-n6<<endl;
cout<<n5<<" / "<<n6<<" = "<<n5/n6<<endl;
system("pause");
return 0;
}
三:(分别用C++标准库的string和cstring实现查字典功能的程序)
Write a function to read several words from keyboard, and store them
in a string array. In the input phrase, the user is required to input a number indicating how many words he will input, then input all the words. Then, write a function find() to print the words start with a
specific character, that is, function find() takes a char argument.
【我的代码】
//string
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main()
{
int num;
cout<<"how many words you will input?"<<endl;
cin>>num;
vector<string>str(num);
for(int i=0;i<num;i++)
{
string s;
cin>>s;
str[i]=s;
}
char k;
cout<<"Tryng to find the words with a specific character: ";
cin>>k;
for(int i=0;i<num;i++)
{
if((str[i].find(k))!=str[i].npos)//string.npos代表不存在的位置
cout<<str[i]<<" ";
}
system("pause");
return 0;
}
//cstring
#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
int main()
{
int num;
cout<<"how many words you will input?"<<endl;
cin>>num;
char **charArray=new char*[num];
for(int i=0;i<num;i++)
charArray[i]=new char[100];
for(int i=0;i<num;i++)
for(int j=0;;j++)
{
char s;
cin>>s;
charArray[i][j]=s;
if(getchar()==' '||getchar()=='\n')break;
}
char k;
cout<<"Tryng to find the words with a specific character: ";
cin>>k;
for(int i=0;i<num;i++)
{
if(charArray[i][0]==k)
cout<<charArray[i]<<" ";
}
system("pause");
return 0;
}
四: String Concatenation
1.Description of the Problem
String concatenation requires two operands—the two strings that are to be concatenated. In the text, we showed how to implement an overloaded concatenation operator that concatenates the second String object to the right of the first String object, thus modifying the first String object. In some applications, it is desirable to produce a concatenated String object without modifying the String arguments. Implement operator+ to allow operations such as string1 = string2 + string3; in which neither operand is modified.
2.Sample Class Definition
#include<iostream>
#include<cstring>
#include<cassert>
using namespace std;
class String
{
friend ostream &operator<<(ostream &output, const String &s);
public:
String(const char * const =""); // conversion constructor
String(const String &); // copy constructor
~String(); // destructor
const String &operator=(const String &);
String operator+(const String &);
private:
char *sPtr; // pointer to start of string
int length; // string length
}; // end class String
#endif
3. Sample Main Function
#include<iostream>
#include"String.h"
usingnamespace std;
int main()
{
String string1, string2("The date is");
String string3(" August 1,1993");
// test overloaded operators
cout << "string1 = string2 + string3\n";
string1 = string2 + string3; // tests overloaded = and + operator
cout << "\""<< string1 << "\" = \""
<< string2<< "\" + \"" << string3 <<"\"" << endl;
return 0;
}
4.SampleOutput
【我的代码】
\\String Concatenation.h
#ifndef STRING_H
#define STRING_H
#include <iostream>
#include <cstring>
#include <cassert>
using namespace std;
class String
{
friend ostream &operator<<(ostream &, const String &);
public:
String(const char * const = ""); // conversion constructor
String(const String &); // copy constructor
~String(); // destructor
const String &operator=(const String &);
String operator+(const String &);
private:
char *sPtr;
int length;
void setString( const char * );
};
#endif
\\String Concatenation.cpp
#include<iostream>
#include<cstring>
#include"String Concatenation.h"
using namespace std;
ostream &operator<<(ostream &output,const String &a)
{
output<<a.sPtr;
return output;
}
void String::setString( const char *s )
{
sPtr=new char[length+1];
if (s!='\0')
strcpy(sPtr,s);
else
sPtr[0]='\0';
}
String::String(const char *const a):
length((a!='\0')?strlen(a):0)
{
setString(a);
} // conversion constructor
String::String(const String &a):length(a.length)
{
setString(a.sPtr);
}// copy constructor
String::~String()
{
delete[]sPtr;
}
const String &String::operator=(const String &a)
{
if(length!=a.length)
{
delete[]sPtr;
length=a.length;
setString(a.sPtr);
}
return *this;
}
String String::operator+(const String &a)
{
String temp;
//delete temp.sPtr;
temp.length=length+a.length;
temp.sPtr=new char[temp.length+1];
strcpy(temp.sPtr,sPtr);
strcpy(temp.sPtr+length,a.sPtr);
return temp;
}
\\String concatenation类.cpp
#include <iostream>
#include "String Concatenation.h"
using namespace std;
int main()
{
String string1, string2("The date is");
String string3(" August 1, 1993");
cout << "string1 = string2 + string3\n";
string1=string2+string3;
cout << "\"" << string1 << "\" = \"" << string2 << "\" + \""
<< string3 << "\"" << endl;
system("pause");
return 0;
}