This repository has been archived on 2026-07-28. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2025-04-13 21:48:15 +03:00

165 lines
5.8 KiB
C++

// #include <iostream>
// #include <array>
// #include <cstdint>
class BlackHole {
int mass;
public:
BlackHole(size_t mass) : mass(mass) {}
size_t get_mass() const {
return mass;
}
template <typename T>
void consume(T* arg) {
if (arg == nullptr) {
std::cout << "There is nothing to consume" << std::endl;
return;
}
size_t arg_mass = sizeof(*arg);
if (std::is_const<T>::value) {
std::cout << "Black hole consumed " << arg_mass << " const bytes" << std::endl;
} else {
std::cout << "Black hole consumed " << arg_mass << " non-const bytes" << std::endl;
}
mass += arg_mass;
delete arg;
return;
}
void consume(void* arg) {
throw std::runtime_error("Black hole has tried to consume void");
return;
}
void consume(const void* arg) {
throw std::runtime_error("Black hole has tried to consume void");
return;
}
void consume(BlackHole* arg) {
if (arg == this) {
throw std::runtime_error("Black hole has tried to consume itself");
return;
}
size_t arg_mass = arg->get_mass();
if (std::is_const<BlackHole>::value) {
std::cout << "Black hole consumed " << arg_mass << " const bytes" << std::endl;
} else {
std::cout << "Black hole consumed " << arg_mass << " non-const bytes" << std::endl;
}
mass += arg_mass;
delete arg;
return;
}
void consume(const BlackHole* arg) {
if (arg == this) {
throw std::runtime_error("Black hole has tried to consume itself");
return;
}
size_t arg_mass = arg->get_mass();
if (std::is_const<BlackHole>::value) {
std::cout << "Black hole consumed " << arg_mass << " const bytes" << std::endl;
} else {
std::cout << "Black hole consumed " << arg_mass << " non-const bytes" << std::endl;
}
mass += arg_mass;
delete arg;
return;
}
template <typename T>
void consume(T arg) {
throw std::runtime_error("Black hole has tried to consume non-pointer");
return;
}
~BlackHole() = default;
};
/*
Требуется реализовать класс BlackHole.
1) Конструктор класса должен принимать аргумент типа size_t, задающий массу чёрной дыры.
2) У класса должен быть метод get_mass() возвращающий текущую массу.
3) У класса должен быть шаблонный метод consume(arg), предназначенный для "поглощения" указателей (см. ниже) и способный принимать аргументы любых типов.
Вызов consume должен вести себя следующим образом.
1) Он должен выбрасывать исключение типа runtime_error (тексты исключений следует взять из примера вывода ниже) в следующих ситуациях:
- При передаче ему аргумента, не являющегося указателем
- Если переданный указатель указывает на void (константный или неконстантный)
- Если чёрная дыра пытается поглотить саму себя
2) Если в качестве аргумента передан нулевой указатель, следует напечатать "There is nothing to consume" и ничего не делать.
3) Если ни одно из выше перечисленных условий не сработало, то аргумент считается корректным указателем и для него нужно выполнить следующие действия:
- Определить "массу" аргумента. Для BlackHole масса определяется через вызов get_mass(), для остальных - через размер указываемого типа в байтах.
- Напечатать "Black hole consumed N non-const bytes", где вместо N нужно подставить массу аргумента. Если в качестве аргумента передан указатель на константный тип, то вместо non-const следует печатать const.
- Добавить массу аргумента к текущей массе чёрной дыры.
- Удалить аргумент через вызов delete.
При подстановке решения студента, следующий код должен работать:
*/
// int main() {
// BlackHole hole(100);
// std::cout << "The initial mass is " << hole.get_mass() << " bytes" << std::endl;
// hole.consume(new int64_t);
// hole.consume(const_cast <const int64_t*>(new int64_t));
// hole.consume(new int32_t);
// hole.consume(static_cast<char*>(nullptr));
// hole.consume(new BlackHole{ 50 });
// hole.consume(new std::array<char, 64>);
// try {
// hole.consume(5);
// }
// catch (std::runtime_error& err) {
// std::cout << "Error: " << err.what() << std::endl;
// }
// try {
// hole.consume(&hole);
// }
// catch (std::runtime_error& err) {
// std::cout << "Error: " << err.what() << std::endl;
// }
// try {
// hole.consume((void*) nullptr);
// }
// catch (std::runtime_error& err) {
// std::cout << "Error: " << err.what() << std::endl;
// }
// std::cout << "The total mass is: " << hole.get_mass() << " bytes" << std::endl;
// return 0;
// }