Что полезно о ссылке на параметр массива?

Поскольку Employee и User - это совершенно два разных объекта, поэтому вы не можете разыграть как ваш случай

Простой пример

Пользователь

[ 110]

Сотрудник

public class Employee extends User {
    //constructor
}

Тогда вы можете сделать это

Employee e = new Employee();
Object o = e;
User = (Employee) o;

Конечно, в этом случае вы не можете поступите противоположным образом: приведите User к Employee

Надеюсь, этот небольшой пример поможет вам ясно понять дело.

24
задан Community 23 May 2017 в 12:18
поделиться

5 ответов

Параметр ссылки на массив не позволяет типу массива преобразовываться в тип указателя. т.е. точный тип массива сохраняется внутри функции. (Например, вы можете использовать трюк sizeof arr / sizeof * arr для параметра и получить количество элементов). Компилятор также выполнит проверку типа, чтобы убедиться, что тип аргумента массива в точности совпадает с типом параметра массива, т.е. если параметр объявлен как массив из 10 целых чисел, аргумент должен быть массивом ровно из 10 ints и ничего больше.

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

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

void foo(int (&arr)[10]); // reference to an array

или

void foo(int (*arr)[10]); // pointer to an array

Возможно, неправильным способом было бы использовать подход «распавшийся».

void foo(int arr[]); // pointer to an element
// Bad practice!!!

Подход «распавшийся» обычно должен быть зарезервирован для массивов размера времени выполнения и обычно сопровождается фактическим размером массива в отдельном параметре

void foo(int arr[], unsigned n); // pointer to an element
// Passing a run-time sized array

Другими словами, действительно нет вопроса «почему», когда дело доходит до ссылки на массив ( или указатель на массив). Вы должны использовать этот метод естественно, по умолчанию, когда можете, если размер массива фиксирован во время компиляции.Вопрос «почему» действительно должен возникнуть, когда вы используете «устаревший» метод передачи массива. «Разложившийся» метод предполагается использовать только как специализированный прием для передачи массивов размера во время выполнения.

Вышесказанное, по сути, является прямым следствием более общего принципа. Когда у вас есть «тяжелый» объект типа T , вы обычно передаете его либо по указателю T * , либо по ссылке T & . Массивы не являются исключением из этого общего принципа. У них нет причин быть.

Имейте в виду, что на практике часто имеет смысл писать функции, которые работают с массивами размера времени выполнения, особенно когда речь идет об общих функциях библиотечного уровня. Такие функции более универсальны. Это означает, что часто есть веская причина использовать «разложившийся» подход в реальном коде. Тем не менее, это не освобождает автора кода от распознавания ситуаций, когда размер массива известен во время компиляции и использования ссылки на -array соответственно.

47
ответ дан 28 November 2019 в 22:47
поделиться

Одно отличие состоит в том, что (предполагается) невозможно передать нулевую ссылку. Таким образом, в теории функции не нужно проверять, является ли параметр нулевым, тогда как параметру int * arr можно было бы передать значение null.

8
ответ дан 28 November 2019 в 22:47
поделиться

Вы можете убедиться, что функция вызывается только для int массивов размера 10. Это может быть полезно с точки зрения проверки типов.

0
ответ дан 28 November 2019 в 22:47
поделиться

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

template<class E, size_t size>
size_t array_size(E(&)[size])
{
    return size;
}

int main()
{
    int test[] = {2, 3, 5, 7, 11, 13, 17, 19};
    std::cout << array_size(test) << std::endl; // prints 8
}

Больше никаких sizeof (test) / sizeof (test [0]) для меня; -)

5
ответ дан 28 November 2019 в 22:47
поделиться

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

0
ответ дан 28 November 2019 в 22:47
поделиться
Другие вопросы по тегам:

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