Stack Overflow на русском Asked by Majestio on November 18, 2021
Набросал вот такой пример:
#include <iostream>
#include <functional>
// ──────────────────────────────────────────────────────────────────────────────
using CallbackType = std::function<void(void*)>;
// ──────────────────────────────────────────────────────────────────────────────
class Karbofos {
CallbackType *Begin = nullptr;
CallbackType *End = nullptr;
public:
const std::string Name = "Карбофос";
void SetCallback(CallbackType *B, CallbackType *E) {
Begin = B;
End = E;
}
void Run() {
if (Begin) (*Begin)(this);
std::cout << "- Не отдам, слон - мой!n";
if (End) (*End)(this);
}
};
// ──────────────────────────────────────────────────────────────────────────────
void Shef(void* i) {
std::cout << "- Стой, живодер " << ((Karbofos*)(i))->Name << "!n";
}
// ──────────────────────────────────────────────────────────────────────────────
void Kollega(void* i) {
std::cout << "- " << ((Karbofos*)(i))->Name << ", ты немец и контрабандист!n";
}
// ──────────────────────────────────────────────────────────────────────────────
int main() {
Karbofos Object;
CallbackType S = Shef;
CallbackType K = Kollega;
Object.SetCallback(&S,&K);
Object.Run();
return 0;
}
Вопрос
Можно ли как-то обойтись без временных переменных Chef
и Kollega
, и сразу нужные ссылки передать в метод SetCallback
?
Вам действительно необходимы указатели на std::function
?
Тоже самое можно сделать и без них:
#include <utility>
#include <iostream>
#include <functional>
//──────────────────────────────────────────────────────────────────────────────
using CallbackType = std::function<void(void*)>;
// ──────────────────────────────────────────────────────────────────────────────
class Karbofos {
CallbackType Begin;
CallbackType End;
public:
const std::string Name = "Карбофос";
void SetCallback(CallbackType B, CallbackType E) {
Begin = std::move(B);
End = std::move(E);
}
void Run() {
if (Begin) Begin(this);
std::cout << "- Не отдам, слон - мой!n";
if (End) End(this);
}
};
// ──────────────────────────────────────────────────────────────────────────────
void Shef(void* i) {
std::cout << "- Стой, живодер " << ((Karbofos*)(i))->Name << "!n";
}
// ──────────────────────────────────────────────────────────────────────────────
void Kollega(void* i) {
std::cout << "- " << ((Karbofos*)(i))->Name << ", ты немец и контрабандист!n";
}
// ──────────────────────────────────────────────────────────────────────────────
int main() {
Karbofos Object;
Object.SetCallback(Shef, Kollega);
Object.Run();
return 0;
}
Answered by Croessmah on November 18, 2021
Т.к. при создании объектов Shef
и Kollega
используется конструктор по умолчанию, получить аналогичные объекты (разве что с той лишь разницей, что память для них будет выделена в куче, а не в стеке) можно с помощью оператора new
и пустых скобок после указания типа. То есть строки
CallbackType S = Shef;
CallbackType K = Kollega;
Object.SetCallback(&S,&K);
Заменятся на лаконичное
Object.SetCallback(new CallbackType(), new CallbackType());
Также обращу внимание на то, что, т.к. память теперь выделена в куче, необходимо будет очистить её соответствующим delete
после использования объектов, либо обернуть всё сие в умные указатели, например, так:
#include <iostream>
#include <functional>
#include <memory>
// ──────────────────────────────────────────────────────────────────────────────
using CallbackType = std::function<void(void*)>;
// ──────────────────────────────────────────────────────────────────────────────
class Karbofos {
// Тут поменял на соотв. типы
std::shared_ptr<CallbackType> Begin = nullptr;
std::shared_ptr<CallbackType> End = nullptr;
public:
const std::string Name = "Карбофос";
// Поменял типы аргументов
void SetCallback(std::shared_ptr<CallbackType> B, std::shared_ptr<CallbackType> E) {
Begin = B;
End = E;
}
void Run() {
if (Begin) (*Begin)(this);
std::cout << "- Не отдам, слон - мой!n";
if (End) (*End)(this);
}
};
// ──────────────────────────────────────────────────────────────────────────────
void Shef(void* i) {
std::cout << "- Стой, живодер " << ((Karbofos*)(i))->Name << "!n";
}
// ──────────────────────────────────────────────────────────────────────────────
void Kollega(void* i) {
std::cout << "- " << ((Karbofos*)(i))->Name << ", ты немец и контрабандист!n";
}
// ──────────────────────────────────────────────────────────────────────────────
int main()
{
Karbofos Object;
// Заменил здесь
Object.SetCallback(std::shared_ptr<CallbackType>(new CallbackType(Shef)), std::shared_ptr<CallbackType>(new CallbackType(Kollega)));
Object.Run();
return 0;
}
P.S. Чтобы привести код к рабочему состоянию, мне потребовалось добавить .c_str()
после ((Karbofos*)(i))->Name
при выводе в обоих случаях.
Answered by V-Mor on November 18, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP