Http://programming-lang.com/ru/comp_programming/liberti/0/j941.html

Предусловия и постусловия описывают свойства отдельных программ. Но экземпляры класса обладают также глобальными свойствами. Их принято называть инвариантами класса

Для многих классов существует ряд условий, которые всегда должны выполняться при завершении работы с функцией-членом класса. Эти обязательные условия также относятся к инвариантам класса.

Может быть весьма полезным определение метода Invariants(), который возвращает значение TRUE только в том случае, если каждое из этих условий является истинным. Затем можно вставить макрос ASSERT(Invariants()) в начале и в конце каждого метода класса. В качестве исключения следует помнить, что метод Invariants() не возвращает TRUE до вызова конструктора и после выполнения деструктора.

 

#define DEBUG

#define SHOW_INVARIANTS

 

#include <iostream>

#include <string >

 

#ifndef DEBUG

#define ASSERT(x)

#else

#define ASSERT(x)

if (! (x)) { cout<< "ERROR!!Assert "<< x << " failed\n";

cout<< " on line " << __LINE__ << "\n";

cout<< " in file " << FILE << "\n";

}

#endif

 

Class String

{ public:

String()                                                    // конструкторы

{ itsString = newchar[1];           //конструкторпоумолчаниюсоздаетстрокунулевойдлины

itsString[0] = '\0';

itsLen=0;

ASSERT(Invariants());

}

String(const char *constcString)                                                 // инициализацияобъектастрокой

{ itsLen = strlen(cString);

itsString = new char[itsLen+1];

for (inti = 0; i<itsLen; i++)

itsString[i] = cString[i];

itsString[itsLen] ='\0';

ASSERT(Invariants());

}

String(const String &rhs)                                                 //конструкторкопирования

{ itsLen=rhs.GetLen();

itsString = new char[itsLen+1];

for (inti = 0; i<itsLen;i++)

itsString[i] = rhs[i];

itsString[itsLen] = '\0';

ASSERT(Invariants());

}

~String()                   //деструктор освобождает выделенную память

{ ASSERT(Invariants());

delete [] itsString;

itsLen = 0;

}

private:

String (intlen)                                         //privateконструктор, используетсятолько для создания

{ itsString = newchar[len+1];               // новой строки требуемого размера.

for (inti = 0; i<=len; i++)                        // При этом вставляется концевой \0

itsString[i] = '\0';           

itsLen=len;

ASSERT(Invariants());

}

char * itsString;

intitsLen                                                   // целочисленнаяпеременнаяitsLen;

 

public:

char& operator [] (int offset)                              //неконстантныйоператор []

 { ASSERT(Invariants());

   if (offset >itsLen)

{ ASSERT(Invariants()); //недопустимыйаргумент - возврат

returnitsString[itsLen-1];// последнегосимволастроки

}

else

{

ASSERT(Invariants());

returnitsString[offset];

}

}

char operator[] (int offset)const//константныйоператор []

{ ASSERT(Invariants());

charretVal;

if (offset >itsLen)

retVal = itsString[itsLen-1];

else

retVal = itsString[offset];

ASSERT(Invariants());

returnretVal;

}

String & operator= (const String &rhs)             //перегрузкаоперации =

{ ASSERT(Invariants());                                      // операторвыполняетсравнение

if (this == &rhs)                

return *this;

delete [] itsString;                                   //освобождает занятуюпамять, 

itsLen = rhs.GetLen();                                                //затем копирует строку и ее размер    

itsString = new char[itsLen+1];

for (inti = 0; i<itsLen;i++)

itsString[i] = rhs[i];

itsString[itsLen] = '\0';

ASSERT(Invariants());

return *this;

}

intGetLen()const{ return itsLen; }       //методыкласса

constchar * GetString() const { return itsString; }

BoolInvariants() const

{ #ifdefSHOW_INVARIANTS

cout<< "Invariants Tested";

#endif

return ((itsLen&&itsString) || (!itsLen&&!itsString));

};

};

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: