Как заполнить интерфейс для существующего объекта? - PullRequest
0 голосов
/ 01 марта 2019

У меня есть интерфейс:

struct result {
  virtual ~result() = 0;
  virtual auto getName() -> std::string = 0;

  protected:
    result() = default;
    result(const result &) = default;
    auto operator=(const result &) -> result & = default;
}

и реализация:

struct abstract_result : public result {
  auto getName() -> std::string override;
  std::string m_name;
}

В настоящее время я использую экземпляр abstract_result в своем коде для заполнения числомалгоритмов, но я хочу, чтобы конечный пользователь получил указатель на интерфейс, чтобы я мог скрыть реализацию.

Как я могу превратить экземпляр abstract_result в std::unique_ptr<result>?

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Если я правильно вас понимаю, то, что вы хотите сделать, очень похоже на то, что говорит @ user463035818, но с заполненной структурой, то есть:

std::unique_ptr<result> pointer_to_result {&my_populated_abstract_result };

И это хорошо, так как, опять же, abstract_result is-a result.Но вы , возможно, не захотите делать это вообще , если ваш my_populated_abstract_result не выделен динамически.std :: unique_ptr обычно не предназначен для использования с объектами в стеке (например, локальными переменными).Если my_populated_abstract_result является локальной переменной - не вставляйте unique_ptr вообще (ни в std::shared_ptr), и не пытайтесь удерживать его, как только my_populated_abstract_result выйдетвне области видимости.

PS:

  • Разве не имеет смысла называть чисто виртуальный базовый класс abstract_result, а конкретные классы - foo_resultbar_result, baz_result?
  • Возможно, будет хорошей идеей использовать пространство имен, если у вас действительно много имен с _result в них?Таким образом, у вас будет result::abstract (или result::base), а затем result::foo, result::bar, result::baz.
0 голосов
/ 01 марта 2019

abstract_result is-a result (кстати, ваше наименование кажется неправильным), поэтому указатель на abstract_result is-указатель на result.Так что вам просто нужно создать unique_ptr, например,

auto x = unique_ptr<result>(new abstract_result());

. Если экземпляр находится в стеке, и вас беспокоит, что unique_ptr попытается удалить экземпляр с помощью автоматического хранилища, вы можете использоватьсредство удаления, которое ничего не делает, как в

template <typename T>
struct no_deleter {
    void operator()(T*){}
};

abstract_result x;
std::unique_ptr<result> x_ptr{ &x, no_deleter<result>() };

Однако, в этом случае мне интересно, почему вы хотите использовать unique_ptr в первую очередь.Нет ничего плохого в использовании необработанных указателей, если они не владеют объектом (т. Е. Тот, кто держит указатель, не отвечает за удаление объекта), тогда как unique_ptr обычно предназначен для владения объектом, на который он указывает.

PS

Я должен признать, что не до конца понимаю, в чем ваша проблема ...

, но я хочу включить заполненный экземпляриз abstract_result в указатель на результат

Как упоминалось выше, указатель на abstract_result является (небрежно говоря) уже указателем на result.Более простой пример:

abstract_result x;
result* pointer_to_result = &x;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...