diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20ffd9f Binary files /dev/null and b/.gitignore differ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ae84608 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.31) +project(incapsulation_lab) + +set(CMAKE_CXX_STANDARD 20) + +add_executable( + incapsulation_lab + + main.cpp + subject.cpp + engine.cpp +) + +add_executable( + tests + + test.cpp + subject.cpp + engine.cpp +) \ No newline at end of file diff --git a/engine.cpp b/engine.cpp new file mode 100644 index 0000000..759ffbb --- /dev/null +++ b/engine.cpp @@ -0,0 +1,22 @@ +// +// Created by User on 12/18/2025. +// +#include "engine.h" +#include + +Engine::~Engine() { + // не удаляем - объекты на стеке + commands.clear(); +} + +void Engine::register_command(WrapperBase* cmd, const std::string& name) { + commands[name] = cmd; +} + +int Engine::execute(const std::string& name, const std::map& args) { + auto it = commands.find(name); + if (it == commands.end()) { + throw std::runtime_error("Command not found"); + } + return it->second->call(args); +} \ No newline at end of file diff --git a/engine.h b/engine.h new file mode 100644 index 0000000..304eb56 --- /dev/null +++ b/engine.h @@ -0,0 +1,20 @@ +// +// Created by User on 12/18/2025. +// +#ifndef ENGINE_H +#define ENGINE_H + +#include +#include +#include "wrapper.h" + +class Engine { + std::map commands; + +public: + ~Engine(); + void register_command(WrapperBase* cmd, const std::string& name); + int execute(const std::string& name, const std::map& args = {}); +}; + +#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..5e250c4 --- /dev/null +++ b/main.cpp @@ -0,0 +1,19 @@ +#include +#include +#include +#include "subject.h" +#include "wrapper.h" +#include "engine.h" + +int main() { + Subject subj; + + Wrapper wrapper(&subj, &Subject::f3, {{"arg1", 0}, {"arg2", 0}}); + + Engine engine; + engine.register_command(&wrapper, "command1"); + + std::cout << engine.execute("command1", {{"arg1", 4}, {"arg2", 5}}) << std::endl; + + return 0; +} \ No newline at end of file diff --git a/subject.cpp b/subject.cpp new file mode 100644 index 0000000..282f716 --- /dev/null +++ b/subject.cpp @@ -0,0 +1,8 @@ +// +// Created by User on 12/18/2025. +// +#include "subject.h" + +int Subject::f3(int arg1, int arg2) { + return arg1 + arg2; +} \ No newline at end of file diff --git a/subject.h b/subject.h new file mode 100644 index 0000000..3f6e25b --- /dev/null +++ b/subject.h @@ -0,0 +1,13 @@ +// +// Created by User on 12/18/2025. +// + +#ifndef SUBJECT_H +#define SUBJECT_H + +class Subject { +public: + int f3(int arg1, int arg2); +}; + +#endif \ No newline at end of file diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..ee30dc9 --- /dev/null +++ b/test.cpp @@ -0,0 +1,54 @@ +// +// Created by User on 12/18/2025. +// +#include +#include +#include +#include +#include "subject.h" +#include "wrapper.h" +#include "engine.h" + +void test_basic() { + // тест по тз + Subject subj; + Wrapper w(&subj, &Subject::f3, {{"arg1", 0}, {"arg2", 0}}); + Engine e; + e.register_command(&w, "command1"); + assert(e.execute("command1", {{"arg1", 4}, {"arg2", 5}}) == 9); + std::cout << "Basic test OK" << std::endl; +} + +void test_defaults() { + // тест с другими значениями по умолчанию + Subject subj; + Wrapper w(&subj, &Subject::f3, {{"x", 10}, {"y", 20}}); + Engine e; + e.register_command(&w, "add"); + assert(e.execute("add") == 30); + assert(e.execute("add", {{"x", 100}}) == 120); + std::cout << "Defaults test OK" << std::endl; +} + +void test_error() { + // тест на ошибку + Subject subj; + Wrapper w(&subj, &Subject::f3, {{"a", 0}, {"b", 0}}); + Engine e; + e.register_command(&w, "test"); + + try { + e.execute("unknown"); + assert(false); // не должны сюда попасть + } catch (const std::runtime_error&) { + std::cout << "Error test OK" << std::endl; + } +} + +int main() { + test_basic(); + test_defaults(); + test_error(); + std::cout << "All tests passed!" << std::endl; + return 0; +} \ No newline at end of file diff --git a/wrapper.h b/wrapper.h new file mode 100644 index 0000000..6fc79c4 --- /dev/null +++ b/wrapper.h @@ -0,0 +1,46 @@ +// +// Created by User on 12/18/2025. +// +#ifndef WRAPPER_H +#define WRAPPER_H + +#include +#include +#include + +class WrapperBase { +public: + virtual ~WrapperBase() {} + virtual int call(const std::map& args) = 0; +}; + +template +class Wrapper : public WrapperBase { + T* obj; + std::function)> func; + std::map defaults; + +public: + Wrapper(T* object, int(T::*method)(int, int), std::map defs = {}) + : obj(object), defaults(defs) { + func = [method](T* o, std::map args) { + auto it = args.begin(); + int a = it->second; + ++it; + int b = it->second; + return (o->*method)(a, b); + }; + } + + int call(const std::map& args) override { + std::map all = defaults; + + for (const auto& pair : args) { + all[pair.first] = pair.second; + } + + return func(obj, all); + } +}; + +#endif \ No newline at end of file