Загрузка данных
#include <iostream>
#include <string>
#include <cstring>
#include <stdexcept>
// ==========================================
// 1. Класс "Жесткий диск"
// ==========================================
class HardDisk {
private:
int volume; // объем в Мбайт (скрытое поле)
public:
// Конструктор по умолчанию
HardDisk() : volume(512) {}
// Конструктор с параметром
HardDisk(int vol) {
setVolume(vol);
}
// Свойство / метод доступа для объема
void setVolume(int vol) {
if (vol <= 0) {
throw std::invalid_argument("Ошибка: объем жесткого диска должен быть положительным числом!");
}
volume = vol;
}
int getVolume() const {
return volume;
}
// Функция печати
void print() const {
std::cout << "Жесткий диск: " << volume << " Мбайт";
}
};
// ==========================================
// 2. Базовый класс "Компьютер"
// ==========================================
class Computer {
private:
char* brand; // марка (указатель на строку)
double price; // цена
HardDisk hardDisk; // композиция: класс содержит объект жесткого диска
public:
// Конструктор по умолчанию
Computer() : price(0.0), hardDisk() {
brand = new char[1];
brand[0] = '\0';
}
// Конструктор с параметрами
Computer(const char* b, double p, const HardDisk& hd) : price(0.0), hardDisk(hd) {
setBrand(b);
setPrice(p);
}
// Конструктор копирования (глубокое копирование для динамической памяти)
Computer(const Computer& other) : price(other.price), hardDisk(other.hardDisk), brand(nullptr) {
if (other.brand) {
brand = new char[strlen(other.brand) + 1];
strcpy(brand, other.brand);
}
}
// Оператор присваивания
Computer& operator=(const Computer& other) {
if (this == &other) return *this;
price = other.price;
hardDisk = other.hardDisk;
char* newBrand = nullptr;
if (other.brand) {
newBrand = new char[strlen(other.brand) + 1];
strcpy(newBrand, other.brand);
}
delete[] brand;
brand = newBrand;
return *this;
}
// Деструктор (очистка динамической памяти)
virtual ~Computer() {
delete[] brand;
}
// Свойства и методы доступа с проверкой исключений
void setBrand(const char* b) {
if (!b) {
throw std::invalid_argument("Ошибка: указатель на строку марки не может быть нулевым!");
}
char* temp = new char[strlen(b) + 1];
strcpy(temp, b);
delete[] brand;
brand = temp;
}
const char* getBrand() const {
return brand;
}
void setPrice(double p) {
if (p < 0.0) {
throw std::out_of_range("Ошибка: цена компьютера не может быть отрицательной!");
}
price = p;
}
double getPrice() const {
return price;
}
void setHardDisk(const HardDisk& hd) {
hardDisk = hd;
}
const HardDisk& getHardDisk() const {
return hardDisk;
}
// Виртуальная функция печати
virtual void print() const {
std::cout << "Марка: " << (brand[0] != '\0' ? brand : "Не указана")
<< ", Цена: " << price << " руб. | ";
hardDisk.print();
}
};
// ==========================================
// 3. Публично производный класс "Компьютер с монитором"
// ==========================================
class PublicComputerWithMonitor : public Computer {
private:
double monitorSize; // размер монитора (в дюймах)
public:
PublicComputerWithMonitor() : Computer(), monitorSize(15.6) {}
PublicComputerWithMonitor(const char* b, double p, const HardDisk& hd, double mSize)
: Computer(b, p, hd) {
setMonitorSize(mSize);
}
~PublicComputerWithMonitor() override {
// Деструктор дочернего класса (базовый деструктор вызывается автоматически)
}
void setMonitorSize(double mSize) {
if (mSize <= 0.0) {
throw std::invalid_argument("Ошибка: размер монитора должен быть больше 0!");
}
monitorSize = mSize;
}
double getMonitorSize() const {
return monitorSize;
}
void print() const override {
std::cout << "[Public Inheritance] ";
Computer::print();
std::cout << ", Размер монитора: " << monitorSize << "\"" << std::endl;
}
};
// ==========================================
// 4. Приватно производный класс "Компьютер с монитором"
// ==========================================
class PrivateComputerWithMonitor : private Computer {
private:
double monitorSize;
public:
PrivateComputerWithMonitor() : Computer(), monitorSize(17.0) {}
PrivateComputerWithMonitor(const char* b, double p, const HardDisk& hd, double mSize)
: Computer(b, p, hd) {
setMonitorSize(mSize);
}
~PrivateComputerWithMonitor() override {}
void setMonitorSize(double mSize) {
if (mSize <= 0.0) {
throw std::invalid_argument("Ошибка: размер монитора должен быть больше 0!");
}
monitorSize = mSize;
}
double getMonitorSize() const {
return monitorSize;
}
// При приватномследовании интерфейс базового класса закрыт снаружи,
// поэтому мы реализуем собственную функцию печати, обращаясь к методам базового класса внутри.
void print() const {
std::cout << "[Private Inheritance] Марка: " << (getBrand() ? getBrand() : "N/A")
<< ", Цена: " << getPrice() << " руб. | ";
getHardDisk().print();
std::cout << ", Размер монитора: " << monitorSize << "\"" << std::endl;
}
};
// ==========================================
// Главная функция (демонстрация работы)
// ==========================================
int main() {
// Установка русской локали для корректного вывода в консоль
std::setlocale(LC_ALL, "Russian");
std::cout << "=== 1. Демонстрация штатной работы классов ===" << std::endl;
try {
HardDisk myHd(1024);
Computer baseComp("ASUS", 75000.0, myHd);
baseComp.print();
std::cout << std::endl;
PublicComputerWithMonitor pubComp("MSI", 120000.0, HardDisk(2048), 27.0);
pubComp.print();
PrivateComputerWithMonitor privComp("Lenovo", 55000.0, HardDisk(512), 23.8);
privComp.print();
}
catch (const std::exception& e) {
std::cerr << "Поймано исключение: " << e.what() << std::endl;
}
std::cout << "\n=== 2. Демонстрация обработки исключений ===" << std::endl;
// Проверка исключения для жесткого диска
try {
std::cout << "Попытка создать жесткий диск с неверным объемом (-500 МБ)..." << std::endl;
HardDisk invalidHd(-500);
}
catch (const std::exception& e) {
std::cerr << "Перехвачено исключение: " << e.what() << std::endl;
}
// Проверка исключения для цены компьютера
try {
std::cout << "\nПопытка задать отрицательную цену компьютера (-1000 руб.)..." << std::endl;
Computer comp;
comp.setPrice(-1000.0);
}
catch (const std::exception& e) {
std::cerr << "Перехвачено исключение: " << e.what() << std::endl;
}
// Проверка исключения для размера монитора
try {
std::cout << "\nПопытка создать монитор с нулевым размером..." << std::endl;
PublicComputerWithMonitor invalidMonitor("HP", 40000.0, HardDisk(512), 0.0);
}
catch (const std::exception& e) {
std::cerr << "Перехвачено исключение: " << e.what() << std::endl;
}
return 0;
}