Untitled

 avatar
unknown
c_cpp
a year ago
13 kB
1
Indexable
#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;
}