Skip to content
Open
Binary file added .gitignore
Binary file not shown.
20 changes: 20 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
)
22 changes: 22 additions & 0 deletions engine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Created by User on 12/18/2025.
//
#include "engine.h"
#include <stdexcept>

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<std::string, int>& args) {
auto it = commands.find(name);
if (it == commands.end()) {
throw std::runtime_error("Command not found");
}
return it->second->call(args);
}
20 changes: 20 additions & 0 deletions engine.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Created by User on 12/18/2025.
//
#ifndef ENGINE_H
#define ENGINE_H

#include <map>
#include <string>
#include "wrapper.h"

class Engine {
std::map<std::string, WrapperBase*> commands;

public:
~Engine();
void register_command(WrapperBase* cmd, const std::string& name);
int execute(const std::string& name, const std::map<std::string, int>& args = {});
};

#endif
19 changes: 19 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <iostream>
#include <map>
#include <string>
#include "subject.h"
#include "wrapper.h"
#include "engine.h"

int main() {
Subject subj;

Wrapper<Subject> 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;
}
8 changes: 8 additions & 0 deletions subject.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// Created by User on 12/18/2025.
//
#include "subject.h"

int Subject::f3(int arg1, int arg2) {
return arg1 + arg2;
}
13 changes: 13 additions & 0 deletions subject.h
Original file line number Diff line number Diff line change
@@ -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
54 changes: 54 additions & 0 deletions test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// Created by User on 12/18/2025.
//
#include <iostream>
#include <map>
#include <string>
#include <cassert>
#include "subject.h"
#include "wrapper.h"
#include "engine.h"

void test_basic() {
// тест по тз
Subject subj;
Wrapper<Subject> 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<Subject> 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<Subject> 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;
}
46 changes: 46 additions & 0 deletions wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// Created by User on 12/18/2025.
//
#ifndef WRAPPER_H
#define WRAPPER_H

#include <map>
#include <string>
#include <functional>

class WrapperBase {
public:
virtual ~WrapperBase() {}
virtual int call(const std::map<std::string, int>& args) = 0;
};

template<typename T>
class Wrapper : public WrapperBase {
T* obj;
std::function<int(T*, std::map<std::string, int>)> func;
std::map<std::string, int> defaults;

public:
Wrapper(T* object, int(T::*method)(int, int), std::map<std::string, int> defs = {})
: obj(object), defaults(defs) {
func = [method](T* o, std::map<std::string, int> args) {
auto it = args.begin();
int a = it->second;
++it;
int b = it->second;
return (o->*method)(a, b);
};
}

int call(const std::map<std::string, int>& args) override {
std::map<std::string, int> all = defaults;

for (const auto& pair : args) {
all[pair.first] = pair.second;
}

return func(obj, all);
}
};

#endif