2013-09-02 1 views
1

Просто интересно, могу ли я получить некоторую обратную связь о том, что я делаю, и является ли это плохой juju.Использование массива, возвращаемого из функции-члена, это нормально?

У меня есть функция-член, которая возвращает 2D массив (двойной указатель разыменования), и это выглядит как ...

int** ClassName::GetArr() const 
{ 
    return arr; 
} 

... и я хотел бы использовать это как так ...

if (my_class_object.GetArr()[i][j] == 1) // do something 

... это нормально?

(И да, я, вероятно, следует использовать вектор, но остается вопрос!)

+3

Будьте в безопасности и используйте вектор. – 0x499602D2

+1

@ 0x499602D2: Согласовано, но в этом случае OP захочет вектор векторов. ;) – thokra

+0

убедитесь, что arr является «новым», а не адресом локальной переменной или массивом – texasbruce

ответ

1

Да это, но будьте осторожны с из ошибок диапазона. и плохой доступ.

0

Да, при условии, что arr имеет выделенную память и правильно инициализирован/настроен, это должно быть хорошо.

0

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

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

Использование std::vector<std::vector<double>>& GetArr() сделает его намного проще и безопаснее.

2

Если вы хотите использовать его как

if (my_class_object.GetArr()[i][j] == 1) 

вы могли бы быть лучше, обеспечивая поглотитель в ClassName

int ClassName::GetValue(int i, int j) const 
{ 
    //possible error checking 
    return arr[i][j]; 
} 

и, очевидно, назвать как этот

if (my_class_object.GetValue(i, j) == 1) 
+1

Это должен быть принятый ответ. –

+0

Должна ли эта форма быть вариантом 'const', где имеется соответствующий вариант, который возвращает ссылку для модификации. –

+0

Да. К сожалению. Исправленный. – doctorlove

0

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

Вы также можете удалить одну косвенную связь за счет небольшого увеличения накладных расходов на индекс. 2D-массив, также может быть представлена ​​в виде массива 1D, которые могут быть доступны, как это:

my_class_object.GetArr()[i * height + j] 

В этом случае предложение Матса Петерсона использовать std::vector из std::vector ы могут быть сведены к одному вектору:

const std::vector<int>& ClassName::GetArr() const // assuming read-only access 
{ 
    return arr; 
} 

Независимо от того, что вы делаете, использование оператора индекса также может инициировать нарушение доступа, поскольку оно по сути имеет тот же эффект, что и доступ к C-массиву, указывающий на недопустимое хранилище.

Легко защитить себя от этого, однако:

size_t index    = i * height + j; 
const std::vector<int>& vec = my_class_object.GetArr(); 
if(index < vec.size()) 
{ 
    // do stuff using the value at the calculated index 
} 

EDIT: Просто, чтобы избавить вас путаницы, индексы я и J должны быть в [0, ВЫСОТА (и [0, ШИРИНА (соответственно, где высота и ширина являются размерами массива по y и x.

Смежные вопросы