Я сталкиваюсь с этим кодом
int n1 = 10;
int n2 = (int &)n1;
Я не понимаю, что значение этого кастинга, n2 не является ссылкой начиная с изменения n1, не отражает n1. Странно этот код бросает ошибку компилятора в gcc где как компиляции, прекрасные в VC ++.
Кто-либо знает значение этого кастинга?
Если предположить, что n2
имеет какой-то встроенный тип, то литой тип int &
выполняет переинтерпретацию значения n1
(независимо от того, какой тип он имел) в качестве значения типа int
.
В контексте декларации int n2 = (int &) n1
, если n1
само по себе является значением типа int
, гипс лишний, он абсолютно ничего не меняет. Если n1
является значением типа const int
, то бросание просто отбрасывает констелляцию, что также лишнее в приведенном выше контексте. Если n1
является значением какого-то другого типа, то отбрасываемая просто переинтерпретирует память, занятую n1
как объект типа int
(это называется типом пробивания int). Если n1
не является значением, то код неправильно сформирован.
Таким образом, в коде типа int n2 = (int&) n1
отбрасывание к int &
не является редуцирующим (имеет некоторый фактический эффект), когда оно делает типовую штамповку, т.е. когда n1
является значением какого-то другого типа (не int
). Например,
float n1 = 5.0;
int n2 = (int &) n1;
, что было бы эквивалентно
int n2 = *(int *) &n1;
и
int n2 = *reinterpret_cast<int *>(&n1);
Нет необходимости говорить, что это довольно плохая практика программирования.
Это, BTW, один из случаев, когда использование выделенного слепка в стиле Си++ сильно предпочтительнее. Если бы автор кода использовал reinterpret_cast
вместо C-style cast, то, наверное, не пришлось бы задавать этот вопрос. Конечно, если n1
сам по себе имеет тип int
, то такого рода кастинг не имеет смысла. В таком случае это опять же совершенно лишнее.
P.S. Также существует вероятность, что n2
- это класс с перегруженным оператором преобразования к типу int &
, что совсем другое дело.... В любом случае, когда вы задаете подобные вопросы, вы должны сказать, что такое n2
.
Это делает очевидную вещь. Назначьте n1
ссылкой на int, а затем присвойте ее int n2
.
И если предположить, что n1
- это int, то он должен скомпилироваться просто отлично.
Он не скомпилируется, если n1
- это значение rvalue. Например:
(int&)foo();
(int&)42;
(int&) (x+y); // assuming x and y are int variables
Это совершенно корректный Си++ код, который компилируется с g++ 4.4.1. Он создает временную ссылку на n1, а затем использует значение, на которое ссылается эта ссылка, для инициализации n2.
Это может быть проще увидеть, если expresed как функция:
void f( int & n1 ) {
int n2 = n1; // initialise with valuue referred to by n1
}
Обратите внимание, что это недействительный код C, так как C не поддерживает ссылки.
.int main()
{
int n1 = 10;
int n2 = (int &)n1;
cout<<n2<<endl;
}
Печатает 10, как и ожидалось.
С актерским составом проблем нет.
Просто создается временная ссылка, как предполагает следующий вывод:
int main()
{
int n1 = 10;
int n2 = (int &)n1;
n2 = 20;
cout<<n1<<endl; // print 10 and not 20.
}
Я думаю, что это, вероятно, опечатка в оригинальном коде.
GCC обычно более педантичен, чем VC++. Однако этот код кажется неплохим, хотя и делает ненужные вещи. В основном создается временная ссылка для n1, а затем конструктор копирования используется для инстанцирования n2.
.Он тоже компилируется в gcc (я просто пытался быть уверенным). Он просто приводит n1 к ссылке.