Функция, которая возвращает указатель на const 2-й массив (C ++) - PullRequest
1 голос
/ 24 июня 2010

Я временный программист и, похоже, недавно забыл много основ.

Я создал класс SimPars для хранения нескольких двумерных массивов; ниже показан demPMFs. Я собираюсь передать указатель на экземпляр SimPars другим классам, и я хочу, чтобы эти классы могли читать массивы, используя функции доступа SimPars. Скорость и память важны.

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

Как мне написать функции доступа для массивов? Если меня интересует индекс n-го массива, как мне получить к нему доступ с помощью возвращенного указателя? (Должен ли я написать отдельную функцию доступа для определенного индекса массива?) Что ниже, безусловно, неправильно.

// SimPars.h
#ifndef SIMPARS_H
#define SIMPARS_H
#include "Parameters.h" // includes array size information

class SimPars {
 public:
  SimPars( void );
  ~SimPars( void );

  const double [][ INIT_NUM_AGE_CATS ] get_demPMFs() const;

 private:
   double demPMFs[ NUM_SOCIODEM_FILES ][ INIT_NUM_AGE_CATS ];

};
#endif


// SimPars.cpp
SimPars::SimPars() {
 demPMFs[ NUM_SOCIODEM_FILES ][ INIT_NUM_AGE_CATS ];
 // ...code snipped--demPMFs gets initialized...
}

//...destructor snipped
const double [][ INIT_NUM_AGE_CATS ] SimPars::get_demPMFs( void ) const {
  return demPMFs; 
}

Я был бы очень признателен за какое-то объяснение предложенных решений.

Ответы [ 3 ]

3 голосов
/ 24 июня 2010

По сути, у вас есть три варианта: вернуть весь массив по ссылке, вернуть первую строку по указателю или вернуть весь массив по указателю.Вот реализация:

typedef double array_row[INIT_NUM_AGE_CATS];

typedef array_row array_t[NUM_SOCIODEM_FILES];

array_t demPMFs;

const array_t& return_array_by_reference() const
{
    return demPMFs;
}

const array_row* return_first_row_by_pointer() const
{
    return demPMFs;
}

const array_t* return_array_by_pointer() const
{
    return &demPMFs;
}

И вот примеры использования:

SimPars foo;

double a = foo.return_array_by_reference()[0][0];
double b = foo.return_first_row_by_pointer()[0][0];
double c = (*foo.return_array_by_pointer())[0][0];

Как бы я вернул только n-ую строку массива?*

Опять же, у вас есть три варианта:

const array_row& return_nth_row_by_reference(size_t row) const
{
    return demPMFs[row];
}

const double* return_first_element_of_nth_row_by_pointer(size_t row) const
{
    return demPMFs[row];
}

const array_row* return_nth_row_by_pointer(size_t row) const
{
    return demPMFs + row;
}
1 голос
/ 24 июня 2010
const double (* get_demPMFs() const)[INIT_NUM_AGE_CATS];

Или используйте typedef (но это не кажется чище ...).

class SimPars {
    typedef const double (*ConstDemPMFType)[INIT_NUM_AGE_CATS];

    double demPMFs[NUM_SOCIODEM_FILES][INIT_NUM_AGE_CATS];
public:
    ConstDemPMFType get_demPMFs() const;
};

Обратите внимание, что вы не можете вернуть массив (g++ отказывается от компиляции). Но массив массивов может быть преобразован в указатель на массив, поэтому последний возвращается.

0 голосов
/ 24 июня 2010

По логике говоря, существует этот вопрос с членом данных. Разрешено ли пользователям изменять его или нет. Если вы хотите дать другому классу полный доступ к члену, вам не обязательно нужен getter / setter, особенно если вы единственный пользователь. Вы можете просто сделать участника публичным.

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

const double& getElem( int x, int y ) const { return demPMF[x][y] }

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

Если вы хотите доработать, оставьте комментарий ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...