Должен ли я вернуть указатель на начало массива или конкретного элемента?

0

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

class example_t
{
   protected:
      int* array;
      size_t size;  

   public:
      example_t(size_t size = 100) : size(size)
      {
         array = new[size];

         // .. fill the array ..
      }

      ~example_t()
      {
         delete[] array;
      }

      size_t get_size(void) const { return size; }   
      int const * get_array(void) const { return array; }
      int get_array_element(size_t n) const { return array[n]; }
};

Какой интерфейс должен быть предпочтительным методом доступа к массиву, get_array()[n] или get_array_element(n)? Я пытаюсь рассмотреть здесь как стиль, так и возможность дублирования вызовов, устраненных оптимизатором, например, если array хранит некоторые индексы в другом массиве и мы хотим вычислить

example_t subset(1000);
for (int i = 0; i < subset.get_size(); i++)
{
   result[subset.get_array_element(i)] = f(input[subset.get_array_element(i)]);
}

то можно было бы надеяться, что повторные вызовы будут устранены компилятором. Может ли выбор интерфейса повлиять на возможные оптимизации?

Примечание. Я знаю, что я мог бы использовать std::vector<int> array, это просто пример.

  • 1
    Рассматривали ли вы перегрузку operator [] ?
  • 2
    И то, и другое невероятно плохо , но разоблачение всего оптом определенно хуже, чем выборочное разоблачение элементов.
Показать ещё 3 комментария
Теги:
arrays

3 ответа

2

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

1

Поскольку это C++, возможно, вы использовали бы оператор [] вместо get_array_element (n), но это просто разные синтаксисы и должны быть одинаковыми с точки зрения производительности.

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

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

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

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

Я бы зашел так далеко, чтобы сказать, что если у вас будет функция, которая возвращает указатель на массив, вы можете просто сделать массив открытым. Трудно представить себе какую-либо выгоду, которую получит метод доступа.

0

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

С другой стороны, стандарт уже существует в виде операторов const и non const [], и я был бы склонен имитировать те, даже если их использование напрямую не подходит.

  • 0
    для данных, не относящихся к POD, вы скорее передадите ссылку (или постоянную ссылку), чем сделаете копию
  • 0
    Если бы это был не POD, я бы действительно вернул ссылку; Предположим, что это POD или даже проще, просто стандартный тип. Я в основном сталкиваюсь с этим, когда у меня есть массив int .
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню