Есть ли способ передать std :: make_unique с различными классами, указанными в функции - PullRequest
0 голосов
/ 24 января 2020

Итак, я получил этот примерный код. Всего здесь используется 4 класса, похожих на банковские счета, причем Account - это базовый класс Abstract. CheckingAccount и SavingsAccount являются производными от абстрактного класса Account, а TrustAccount является производным от SavingsAccount. Я не буду подробно описывать здесь внутреннюю работу классов, так как это не имеет значения для проблемы. Я хотел реализовать простую обработку исключений с try и catch и классом, производным от std::exception, содержащим предупреждение об исключении. Я мог бы написать функцию, которая делает это для n объектов, но только если бы они были одним и тем же подклассом Account. Однако я хочу добавить 3 разных подкласса к вектору и не могу придумать, как его автоматизировать.

#include <iostream>
#include <memory>
#include <vector>
#include "checking_account.h"
#include "trust_account.h"
#include "account_util.h"

int main() {
    std::vector<std::unique_ptr<Account>> accounts{};    //A vector of unique_ptr to Account objects that I will be adding new Objects to
    std::unique_ptr<Account> 
    try {
        accounts.push_back(std::make_unique<CheckingAccount>("Joe", 200));
    }
    catch (const std::exception &ex) {
        std::cout << ex.what() << std::endl;
    }
    try {
        accounts.push_back(std::make_unique<TrustAccount>("John", -300, 0.1));
    }
    catch (const std::exception &ex) {
        std::cout << ex.what() << std::endl;
    }
    try {
        accounts.push_back(std::make_unique<SavingsAccount>("Jane", 150, 0.2));
    }
    catch (const std::exception &ex) {
        std::cout << ex.what() << std::endl;
    }
    return 0;
}

Я бы хотел, чтобы функция выглядела так

void create_account(std::vector<std::unique_ptr<Account>> &accounts, CLASS, CLASS_ARGS) {
    try {
        accounts.push_back(std::make_unique<CLASS>(CLASS_ARGS));
    }
    catch (const std::exception &ex) {
        std::cout << ex.what() << std::endl;
    }
}

Но теперь у меня есть идея, как это могло бы выглядеть. Есть ли способ создать указатель на класс? (класс не является объектом класса, я думаю, что есть способ создать указатель на функцию и передать его в качестве параметра, но я не знаю, как это работает).

1 Ответ

3 голосов
/ 24 января 2020

Сделать create_account() шаблонной функцией, например:

template<typename T, typename... ArgTypes>
void create_account(std::vector<std::unique_ptr<Account>> &accounts, ArgTypes&&... args)
{
    try {
        accounts.push_back(std::make_unique<T>(std::forward<ArgTypes>(args)...));
    }
    catch (const std::exception &ex) {
        std::cout << ex.what() << std::endl;
    }
}
int main() {
    std::vector<std::unique_ptr<Account>> accounts;
    create_account<CheckingAccount>(accounts, "Joe", 200);
    create_account<TrustAccount>(accounts, "John", -300, 0.1);
    create_account<SavingsAccount>(accounts, "Jane", 150, 0.2);
    return 0;
}
...