Эффективные альтернативы для представления Набора

Иногда (например, в дистрибутиве osgeo4w) tkinter удаляется.

Попробуйте изменить редактирование базы данных matplotlib matplotlibrc файл, расположенный в [python install dir]/matplotlib/mpl-data/matplotlibrc изменении. Бэкэнд от backend: TkAgg к чему-то другому, подобному backend: Qt4Agg, как описано здесь: http://matplotlib.org/faq/usage_faq.html#what-is-a-backend

12
задан Sebastian 5 August 2016 в 07:41
поделиться

10 ответов

Ответ RichQ является разумной техникой при использовании массива, вектора, и т.д.

При использовании набора, который не индексируется порядковыми номерами..., или думайте, что Вы, возможно, должны были бы в какой-то момент в ближайшем будущем... затем Вы могли бы хотеть рассмотреть представление Вашего собственного типа (типов) итератора, и связанный begin()/end() методы:

class Blah
{
public:
   typedef std::vector<mydata> mydata_collection;
   typedef myDataCollection::const_iterator mydata_const_iterator;

   // ...

   mydata_const_iterator data_begin() const 
      { return myPreciousData.begin(); }
   mydata_const_iterator data_end() const 
      { return myPreciousData.end(); }

private:
   mydata_collection  myPreciousData;
};

... который можно затем использовать нормальным способом:

Blah blah;
for (Blah::mydata_const_iterator itr = blah.data_begin();
   itr != blah.data_end();
   ++itr)
{
   // ...
}
5
ответ дан 2 December 2019 в 18:23
поделиться

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

#include <algorithm>
#include <boost/function.hpp>

class Blah
{
  public:
     void for_each_data(const std::function<void(const mydata&)>& f) const
     {
         std::for_each(myPreciousData.begin(), myPreciousData.end(), f);
     }

  private:
     typedef std::vector<mydata> mydata_collection;
     mydata_collection  myPreciousData;
};

С этим подходом Вы ничего не выставляете о своих внутренностях, т.е. что у Вас даже есть набор.

7
ответ дан 2 December 2019 в 18:23
поделиться

Возможно, что-то вроде этого?

const std::vector<mydata>& getData()
{
  return _myPrivateData;
}

Преимущество здесь - то, что это очень, очень просто, и столь же безопасно как Вы getin C++. Можно бросить, это, как RobQ предлагает, но нет ничего, что можно сделать, который предотвратил бы кого-то от этого, если Вы не копируете. Здесь, необходимо было бы использовать const_cast, который довольно легко определить, если Вы ищете его.

Итераторы, альтернативно, могли бы получить Вас в значительной степени то же самое, но это более сложно. Единственное дополнительное преимущество использования итераторов здесь (что я могу думать) - то, что у Вас может быть лучшая инкапсуляция.

3
ответ дан 2 December 2019 в 18:23
поделиться

Использование ссылки константы или совместно использованного указателя только поможет, если содержание базового набора не будет изменяться со временем.

Рассмотрите свой дизайн. Вызывающая сторона должна действительно видеть внутренний массив? Можно ли реструктурировать код так, чтобы вызывающая сторона сказала объект, что сделать с массивом? Например, если вызывающая сторона намеревается искать массив, объект владельца мог бы сделать это?

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

Я рекомендовал бы пытаться перепроектировать сначала, идя с чистым вторым решением, оптимизировав для трети производительности (при необходимости).

2
ответ дан 2 December 2019 в 18:23
поделиться

То, что Вы хотите, является доступом только для чтения, не копируя весь блоб данных. У Вас есть пара опций.

Во-первых, Вы могли просто возвратить константу refererence тому, что Ваш контейнер данных, как предложенный выше:

const std::vector<T>& getData() { return mData; }

Это имеет недостаток конкретности: Вы не можете измениться, как Вы храните данные внутренне, не изменяя интерфейс Вашего класса.

Во-вторых, можно возвратить указатели редактора константы на фактические данные:

const T* getDataAt(size_t index)
{
   return &mData[index];
}

Это немного более хорошо, но также и требует, чтобы Вы обеспечили вызов getNumItems и защитили от за пределы индексов. Кроме того, мыс константы Ваших указателей легко выброшен, и Ваши данные являются теперь чтением-записью.

Другая опция состоит в том, чтобы обеспечить пару итераторов, которая немного более сложна. Это имеет те же преимущества указателей, а также (не обязательно) бывший должный обеспечить вызов getNumItems, и существует значительно больше работы, включенной для лишения итераторов их мыса константы.

Вероятно, самый легкий способ управлять этим при помощи Диапазона Повышения:

typedef vector<T>::const_iterator range_iterator_type;
boost::iterator_range< range_iterator_type >& getDataRange()
{
    return boost::iterator_range(mData.begin(), mData.end());
}

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

1
ответ дан 2 December 2019 в 18:23
поделиться

Одно преимущество и решений @Shog9 и @RichQ состоит в том, что они отделяют клиент от реализации набора.

Если Вы решите, что th изменяют Ваш тип набора на что-то еще, то Ваши клиенты будут все еще работать.

2
ответ дан 2 December 2019 в 18:23
поделиться

Используя константу разумный выбор. Можно также хотеть проверить повышение библиотека C++ для их общей реализации указателя. Это обеспечивает преимущества указателей, т.е. у Вас может быть требование для возврата общего указателя на "пустой указатель", который не позволила бы ссылка.

http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/smart_ptr.htm

В Вашем случае Вы сделали бы константу типа общего указателя для запрещения записей.

0
ответ дан 2 December 2019 в 18:23
поделиться

Если у Вас есть a std::list из простых данных (что.NET назвала бы 'типами значения'), затем возвращая ссылку константы на тот список будет прекрасен (игнорирование злых вещей как const_cast)

Если у Вас есть a std::list из указателей (или boost::shared_ptr) затем это только остановит Вас изменяющий набор, не объекты в наборе. Мой C++ слишком ржав, чтобы смочь сказать Вам ответ на это в этой точке :-(

0
ответ дан 2 December 2019 в 18:23
поделиться

В следующих двух статьях подробно рассматриваются некоторые проблемы, связанные с инкапсуляцией контейнерных классов, и необходимость в них. Хотя они не обеспечивают полностью отработанное решение, они, по сути, приводят к тому же подходу, что и Shog9.

Часть 1: Инкапсуляция и вампиры
Часть 2 (теперь требуется бесплатная регистрация, чтобы прочитать это): Обнаружение крушения поезда
, Кевлин Хенни

0
ответ дан 2 December 2019 в 18:23
поделиться

. Я предлагаю использовать обратные вызовы в соответствии с EnumChildWindows . Вам нужно будет найти какие-то средства, чтобы запретить пользователю изменять ваши данные. Можно использовать указатель / ссылку const .

С другой стороны, вы можете передать копию каждого элемента функции обратного вызова, каждый раз перезаписывая копию. (Вы не хотите создавать копию всей своей коллекции. Я предлагаю делать копию только одного элемента за раз. Это не займет много времени / памяти).

MyClass tmp;
for(int i = 0; i < n; i++){
    tmp = elements[i];
    callback(tmp);
}
0
ответ дан 2 December 2019 в 18:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: