#include <iostream>
#include <sstream>
#include <string>
#include <windows.h>
using namespace std;
// класс для обработки исключения
// необходим только для создания объекта при вырасывании исключения, св
class RangeException {
private:
string message; // текст ошибки
public:
RangeException( const string &mes ) :
message( mes ) {
}
const string& GetMessage() const {
return message;
}
};
// класс для обработки исключения
// необходим только для создания объекта при вырасывании исключения
class NameException {
private:
string message; // поле - текст ошибки
public:
// конструктор принимает параметры для того чтобы собрать строку
NameException( const string &name, const int low, const int high ) {
stringstream stream;
stream << "Некорректная длина имени: \"" << name << "\" !\n" << "Длина имени должна быть в пределах от " << low
<< " до " << high << ".";
message = stream.str(); // получаем строку из строкового потока с помощью метода str и запоминаем в поле message
}
const string& GetMessage() const {
return message;
}
};
// базовый класс - Организация
class Organization {
private:
int countEmployees; // поле количество сотрудников
string name; // поле название организации
// закрытый метод для проверки валидности количества сотрудников
bool IsValidCount( const int cnt ) {
return cnt >= MIN_COUNT && cnt <= MAX_COUNT;
}
// закрытый метод для проверки валидности названия организации
bool IsValidName( const string &name ) {
return name.length() >= MIN_LEN && name.length() <= MAX_LEN;
}
public:
// открытые статические константы
static const int MIN_COUNT, MAX_COUNT; // количество сотрудников
static const string::size_type MIN_LEN, MAX_LEN; // длина названия организации
Organization( const int count, const string &name );
Organization();
int GetCountemployees() const {
return countEmployees;
}
void SetCountemployees( const int count );
const string& GetName() const {
return name;
}
void SetName( const string& name );
};
const int Organization::MIN_COUNT = 5;
const int Organization::MAX_COUNT = 100000;
const string::size_type Organization::MIN_LEN = 3;
const string::size_type Organization::MAX_LEN = 100;
Organization::Organization( const int count, const string &name ) {
SetCountemployees( count );
SetName( name );
}
Organization::Organization() :
// инициализируем поля значениями по умолчанию
countEmployees( 0 ), name( "Default Name" ) {
}
void Organization::SetCountemployees( const int count ) {
if ( !IsValidCount( count ) ) { // проверяем на валидность количество сотрудников
stringstream stream;
stream << "Количество сотрудников должно быть от " << MIN_COUNT << " до " << MAX_COUNT << "!";
// выбрасываем исключение - создавая объект класса RangeException, передаём в качестве параметра конструктора
// строку из строкового потока
throw RangeException( stream.str() ); // прерываем выполнение метода
}
countEmployees = count; //если исключения НЕ было, то присваиваем полю countEmployees значение параметра count
}
void Organization::SetName( const string& name ) {
if ( !IsValidName( name ) ) // проверяем на валидность название организации
// выбрасываем исключение - создавая объект класса NameException, передаём в качестве параметров конструктора
// название организации, мин. длину, макс. длину возможного названия организации
throw NameException( name, MIN_LEN, MAX_LEN );
this->name = name; //если исключения НЕ было, то присваиваем полю name значение параметра name
}
// класс финансовая организация - наследуемся от класса Organization
class FinanceOrg: public Organization {
private:
int tin, revenue; // закрытые поля класса: ИНН, годовой доход
bool IsValidTin( const int tin ) {
return tin >= MIN_TIN && tin <= MAX_TIN;
}
bool IsValidRevenue( const int revenue ) {
return tin >= MIN_REVENUE && tin <= MAX_REVENUE;
}
public:
static const int MIN_TIN, MAX_TIN, MIN_REVENUE, MAX_REVENUE;
FinanceOrg( const int count, const string &name, const int tin, const int revenue );
FinanceOrg();
int GetTin() const {
return tin;
}
int GetRevenue() const {
return revenue;
}
void SetTin( const int tin );
void SetRevenue( const int revenue );
};
const int FinanceOrg::MIN_TIN = 1000000;
const int FinanceOrg::MAX_TIN = 99999999;
const int FinanceOrg::MIN_REVENUE = 0;
const int FinanceOrg::MAX_REVENUE = 2000000000;
FinanceOrg::FinanceOrg( const int count, const string &name, const int tin, const int revenue ) :
// вызываем конструктор с параметрами родительского класса
Organization( count, name ) {
// присваиваем с помощью суттеров значения полям класса
SetTin( tin );
SetTin( revenue );
}
FinanceOrg::FinanceOrg() :
// вызываем конструктор БЕЗ параметров родительского класса
Organization(), tin( MIN_TIN ), revenue( MIN_REVENUE ) {
}
void FinanceOrg::SetTin( const int tin ) {
stringstream stream;
if ( !IsValidTin( tin ) ) {
stream << "Номер ИНН должен быть от " << MIN_TIN << " до " << MAX_TIN << "!";
throw RangeException( stream.str() );
}
this->tin = tin;
}
void FinanceOrg::SetRevenue( const int revenue ) {
stringstream stream;
if ( !IsValidRevenue( revenue ) ) {
stream << "Значение дохода должно быть от " << MIN_REVENUE << " до " << MAX_REVENUE << "!";
throw RangeException( stream.str() );
}
this->revenue = revenue;
}
// класс государственная организация - наследуемся от класса Organization
class StateOrg: public Organization {
private:
int tin, yearlyBudget;
bool IsValidTin( const int tin ) {
return tin >= MIN_TIN && tin <= MAX_TIN;
}
bool IsValidBudget( const int budget ) {
return tin >= MIN_BUDGET && tin <= MAX_BUDGET;
}
public:
static const int MIN_TIN, MAX_TIN, MIN_BUDGET, MAX_BUDGET;
StateOrg( const int count, const string &name, const int tin, const int budget );
StateOrg();
int GetTin() const {
return tin;
}
int GetBudget() const {
return yearlyBudget;
}
void SetTin( const int tin );
void SetBudget( const int budget );
};
const int StateOrg::MIN_TIN = 10000;
const int StateOrg::MAX_TIN = 99999;
const int StateOrg::MIN_BUDGET = 10000;
const int StateOrg::MAX_BUDGET = 9999999;
StateOrg::StateOrg( const int count, const string &name, const int tin, const int budget ) :
Organization( count, name ) {
SetTin( tin );
SetBudget( budget );
}
StateOrg::StateOrg() :
Organization( ), tin( MIN_TIN ), yearlyBudget( MIN_BUDGET ) {
}
void StateOrg::SetTin( const int tin ) {
stringstream stream;
if ( !IsValidTin( tin ) ) {
stream << "Значение ИНН должно быть от " << MIN_TIN << " до " << MAX_TIN << "!";
throw RangeException( stream.str() );
}
this->tin = tin;
}
void StateOrg::SetBudget( const int budget ) {
stringstream stream;
if ( !IsValidBudget( budget ) ) {
stream << "Значение годового бюджета должно быть от " << MIN_BUDGET << " до " << MAX_BUDGET << "!";
throw RangeException( stream.str() );
}
this->yearlyBudget = budget;
}
// класс государственный банк - наследуемся от классов FinanceOrg и StateOrg
class NationalBank: public FinanceOrg, public StateOrg {
public:
NationalBank( const int count, const string &name, const int tinFinance, const int tinState, const int revenue, const int budget );
NationalBank();
};
NationalBank::NationalBank( const int count, const string &name, const int tinFinance, const int tinState, const int revenue, const int budget ) :
// вызываем конструкторы с параметрами родительских классов
FinanceOrg( count, name, tinFinance, revenue ), StateOrg( count, name, tinState, budget ) {
}
NationalBank::NationalBank() :
// вызываем конструкторы БЕЗ параметров родительских классов
FinanceOrg( ), StateOrg( ) {
}
int GetNaturalNumber( const string& mes, const int low, const int high ) {
string nStr;
int n;
while( true ) {
cout << mes << " от " << low << " до " << high << ": ";
getline( cin, nStr ); // считываем строку неограниченной длины, до нажатия Enter
// пробуем найти ЛЮБОЙ символ, НЕ входящий в набор 0123456789
if ( nStr.find_first_not_of( "0123456789" ) == string::npos ) { // если НЕ нашли, то введено целое число
stringstream ss;
ss << nStr; // отдаём строковому потоку строку, которая представляет собой запись целого полоительного числа
ss >> n; // просим строковый поток вернуть нам int значение
if( n >= low && n <= high )
break;
}
cout << "Ошибка ввода! Значение должно быть " << "от " << low << " до " << high << "!" << endl;
}
return n;
}
int main() {
SetConsoleCP ( 1251 );
SetConsoleOutputCP ( 1251 );
// создание объекта класса NationalBank без параметров
NationalBank bank(); //( 1000, "State First National Bank of Russia", );
// пример алмаза смерти - неоднозначно вызывается метод GetTin,
// так как неясно к какому классу будет относится данный метод: FinanceOrg или StateOrg
// cout << bank.GetTin() << endl; //
// метод GetTin присутствует в обоих родительских классах
cout << bank.StateOrg::GetTin() << endl;
cout << bank.FinanceOrg::GetTin() << endl;
try {
int countEmployees = GetNuturalNumber( "колво сотрудников ",StateOrg::MIN_COUNT, StateOrg::MAX_COUNT );
int tin = GetNuturalNumber("ИНН", StateOrg::MIN_TIN, StateOrg::MAX_TIN );
int tin = GetNuturalNumber( "Инн", FinanceOrg::MIN_TIN, StateOrg::MAX_TIN );
int revenue = GetNuturalNumber( "Бюджет",StateOrg::MIN_REVENUE, StateOrg::MAX_REVENUE );
int yearlyBudget = GetNuturalNumber("годовой бюджет" ,StateOrg::MIN_BUDGET, StateOrg::MAX_BUDGET );
string name;
cout << "Название: ";
getline( cin, name );
} catch ( const RangeException &err ) {
cout << err.GetMessage() << endl;
} catch ( const NameException &err ) {
cout << err.GetMessage() << endl;
/*
try
ввод параметров банка
catch
RangeException
catch
NameException
*/
NationalBank bank2 ( cnt, name ,tinFinance, tinState, revenue, budget);
// метод GetBudget присмутствует ТОЛЬКО в одном классе StateOrg
// можно ( но НЕ нужно ) вызвать метод с уточнением к какому классу принадлежит метод
// bank2.StateOrg::GetBudget()
cout << "Бюджет банка = " << bank2.GetBudget() << endl;
cout << "ИНН = " << bank2.GetTin() << endl;
cout << "доход = " << bank2.GetBudget() << endl;
cout << "Количество сотрудников = " << bank2.GetCountemployees() << endl;
cout << "Имя организаици = " << bank2.GetName() << endl;
return 0;
}