Помогни ни да направим Uroci.net по - богат! Добави урок

C++ част.7 (Член функции на клас)

C++ » C++
fix3d   трудност:    видян: 43587



Фиг. 7.2 Програмен пример за използуване на BitVector

#ifndef BITVECTOR_H

#define BITVECTOR_H

#ifdef vax

const BITSPERBYTE = 8;

const BYTESPERWORD = 4;

#endif

#ifdef sunconst BITSPERBYTE = 8;

const BYTESPERWORD = 2;

#endifconst WORDSIZE = BITSPERBYTE * BYTESPERWORD;

enum { OFF, ON };

typedef unsigned int BitVecType;

typedef BitVecType *BitVec;

#include <iostream.h>

class BitVector

{friend ostream&operator<<( ostream&, BitVector& );

public:

BitVector( int = WORDSIZE, int = OFF );

~BitVector() { delete [wordWidth] bv; }

void operator+=( int pos ); // turn on pos

void operator-=( int pos ); // turn off pos

BitVector operator &( BitVector& );

BitVector operator |( BitVector& );

operator == ( int pos ); // pos is on

operator != ( int pos ); // pos is off

void reset(); // reinit to 0 private: // helping functions

void checkBounds( int );

inline getOffset( int );

inline getIndex( int );

private: // internal representation short wordWidth;short size;

BitVec bv;

};

#indif

Фиг. 7.3 BitVector.h

Упражнение 7-26. Променете представителя на оператора за изход на BitVector така че да сгъстява последователните битове с еднаква стойност. Например, ако текущия изход е:

< 0, 1, 2, 3, 4, 5, 6, 7 >< 0, 2, 3, 4, 7, 8, 9, 12 >

Реализирайте оператора за изход така че да групира последователните стойности като отделена с тире двойка. Например,

< 0 - 7 >
< 0, 2 - 4, 7 - 9, 12 >





7.5. Конвертори, дефинирани от потребителя

Предварително дефинираните стандартни конвертори за вградените типове данни предотвратяват комбинаторния взрив от оператори и презаредими функции. Например, без аритметичните конвертори следните шест операции събиране ще изискват уникални реализации:

char ch;
short sh;
int ival;// widout type conversion, each addition
// would require a unique operationch + ival;
ival + ch;ch + sh;
sh + ch;ival + sh;
sh + ival;

Чрез аритметичните конвертори всеки операнд се преобразува към типа int. Необходима е само една операция - за събиране на две цели стойности. Тези преобразувания се обработват неявно от компилатора и следователно са прозрачни за потребителя.

В този раздел ще разгледаме как проектантът на един клас може да предложи набор от конвертори за класа. Тези конвертори се извикват неявно от компилатора когато е необходимо. За да илюстриране на нашето обсъждане ще реализираме класа SmallInt.

Класът SmallInt може да поддържа стойности от един и същ обхват като 8-битови unsigned char - т.е. 0 - 255. Допълнителни възможности са, че се откриват грешки, свързани с малки и големи числа, излизащи извън обхвата. Иначе, искаме класът да се държи по същия начин както и unsigned char. Например, ние бихме желали да добавяме и изваждаме обекти на SmallInt помежду си или с вградените аритметични типове. За поддържането на тези операции трябва да реализираме шест оператор функции на SmallInt:

class SmallInt
{
friend operator+( SmallInt&, int );
friend operator-( SmallInt&, int );
friend operator-( int, SmallInt& );
friend operator+( int, SmallInt& );public:
operator+( SmallInt& );
operator-( SmallInt& );// ...};

Необходими са само шест оператора понеже вградените аритметични типове ще бъдат конвертирани за да съответствуват на операнд от тип int. Например, изразът

SmallInt si( 3 );si + 3.14159
се изчислява на две стъпки:

1. Константата от тип double 3.14159 се преобразува до цялата стойност 3.
2. Извиква се operator+(si,3), който връща стойност 6.

Ако също така желаем да бъдат поддържани побитови, логически, релационни и съставни оператори за присвояване броят на необходимите оператори става направо обезсърчаващ. Вместо това ние ще предпочетем един начин за преобразуване на обекти на класа SmallInt към int.

С++ предлага механизъм чрез който всеки клас може да дефинира набор от конвертори, които да могат да бъдат прилагани над обектите на класа. За SmallInt ще дефинираме конвертор за обект на SmallInt към тип int. Ето реализацията:

class SmallInt
{
public:// conversion operator:
SmallInt ==> int operator int() { return value; }
// ...private:
int value;};

Конверторите, дефинирани от потребителя, за типа клас предлагат набор от правила за преобразуване на обекти на класа. Те дефинират позволените преобразувания, които могат да бъдат изпълнявани върху конкретни обекти на класа. Освен това те определят какво означава за компилатора преобразуванието. Един обект на класа SmallInt вече може да бъде използван навсякъде, където може да бъде използуван обект от тип int. Например, изразът

SmallInt si( 3 );si + 3.14159;

сега се изпълнява на следните две стъпки:

1. Извиква се оператора конвертор на SmallInt, който дава цялата стойност 3.
2. Цялата стойност 3 се преобразува до 3.0 е се събира с константата от тип double 3.14159, кото се получава стойност 6.14159.

Слeдната програма илюстрира използуването на класа SmallInt:

#include <stream.h>
#include "SmallInt.h"
SmallInt si1, si2;
main() {
cout << "enter a SmallInt, please: ";
while ( cin >> si1 )
{ cout << "nnThank you.n";
cout << "The value read is "<< si1 << "nIt is ";//
SmallInt::Operator int() invoked twice cout << (( si1 > 127 )
? "greater than ": (( si1 < 127 )?
"less than ": "equal to ")) << "127n";
cout << "nenter a SmallInt, please (ctrl-d to exit): ";
}
cout << "bye nown";}

Когато компилираме и изпълним тази програма ще получим следния резултат:

enter a SmallInt, please: 127
Thank you.
The value read is 127
It is equal to 127 enter a SmallInt, please (ctrl-d to exit): 126
Thank you.
The value read is 126
It is less to 127
enter a SmallInt, please (ctrl-d to exit): 128
Thank you.
The value read is 128
It is greater to 127
enter a SmallInt, please (ctrl-d to exit): 256
***SmallInt range error: 256 ***

Реализацията на класа SmallInt изглежда така:

#include <stream.h>
class SmallInt {
friend istream&operator>>(istream& is, SmallInt& s);
friend ostream&operator<<(ostream& os, SmallInt& s)
{ return ( os << s.value ); }
public:SmallInt(int i=0) : value(rangeCheck(i) );
}

int operator=(int i)
{ return( value = rangeCheck(i) ); }
operator int() { return value; }
private:
enum { ERRANGE = -1 };
int rangeCheck( int );
int error( int );
int value;
};

Член функциите, дефинирани вън от тялото на класа изглеждат така:

istream& operator>>( istream& is, SmallInt& si )
{
int i;
is >> i;
si = i; // SmallInt::Operator=(int)
return is;}
SmallInt::error( int i )
{

cerr << "n***SmallInt range error: "<< i << " ***n";
return ERRANGE;}ю
SmallInt::rangeCheck( int i )
{// if any bits are set other than the first 8
// value is too large: report, then exit
if ( i & ~0377 )exit( error( i ) ); // stdlib.h
return i;}

Упражнение 7-27. Защо презаредимият оператор за вход не е реализиран по следния начин?

istream& operator>>( istream& is, SmallInt & si )
{return ( is >> si.value );}


Страници: «6 7 8 9 10 11 »

Сподели урока:



Регистрирайте се, за да добавите коментар


Калдейта Ком ЕООД - © 2003-. Всички права запазени.
Препоръчваме: IT Новини