Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Приведение типов и указатели

24K
27 февраля 2007 года
Игорь В.
4 / / 25.02.2007
Два вопроса по приведению типов:

1) Почему не компилируется следующий код:

int *i;
void*& RefPtr = (void*)i;

Создается временная non-lvalue переменная?

2) Почему, например, int** не приводится к void** неявно?

Используемы компиляторы: gcc, VS 6.0.
1
27 февраля 2007 года
kot_
7.3K / / 20.01.2000
Цитата: Игорь В.
Два вопроса по приведению типов:

1) Почему не компилируется следующий код:

int *i;
void*& RefPtr = (void*)i;

Создается временная non-lvalue переменная?

2) Почему, например, int** не приводится к void** неявно?

Используемы компиляторы: gcc, VS 6.0.


1. Потому что по сути пытаются привести указатель на тип к указателю на ссылку. Кстати билдер это откомпилировал без проблем. вижуал отказался, что вобщем то верно.
2. Зачем?

547
27 февраля 2007 года
Hydra
488 / / 20.06.2006
А кто-нть может сказать, что вообще может означать
 
Код:
int &n=10;

и чем это отличается от
 
Код:
int n=10;

И зачем вообще использовать амперсанд в описании переменных (слева).
361
27 февраля 2007 года
Odissey_
661 / / 19.09.2006
В gcc проблема (с компиляцией) решается следующим образом:
 
Код:
int  *i;
    void *& RefPtr = reinterpret_cast<void *&> (i);

Я вообщем то, понимаю, что любой код имеет право на существование... но интересно, правда, зачем это конструкция? Указатели на ссылки запрещены...
1
27 февраля 2007 года
kot_
7.3K / / 20.01.2000
Цитата: Hydra
А кто-нть может сказать, что вообще может означать
 
Код:
int &n=10;

и чем это отличается от
 
Код:
int n=10;

И зачем вообще использовать амперсанд в описании переменных (слева).


Не очень понятен вопрос. Что такое ссылка известно?
Хотя в приведенном коде правильней было бы так:

 
Код:
int n=10;
int &reff = n;

объявлена переменная целого типа и объявлена ссылка на нее.
24K
28 февраля 2007 года
Игорь В.
4 / / 25.02.2007
void*& RefPtr - это ссылка на указатель а не указатель на ссылку!
Но раз возникли недоразумения, приведу еще один пример:

typedef void* VoidPtr;
void Test(VoidPtr &)
{}

int main(int argc, char* argv[])
{
int i = 0;
int *iPtr = &i;

Test((VoidPtr)iPtr);

return 0;
}

Вот этот код также не компилируется. Компилируется только если я явно привожу iPtr к ссылке при вызове Test. То-есть:
Test((VoidPtr&)iPtr);

Также компилируется, если Test вызыввается без приведения типов:
void *vPtr = i;
Test(vPtr);


Я интересовался этим вопросом на работе. Мало кто смог более-менее внятно объяснить, в чем здесь дело. На сколько я понял, после приведения типа объект перестает быть lvalue. Некоторые еще утверждают, что при приведении типов создается временный объект.
Хотелось бы услышать более информативный ответ. В частности, если временный объект создается, то: всегда ли при приведении типов? как это происходит? и т.д.

Также буду благодарен, если посоветуете хорошее описание работы компилятора С++. Меня не интересуют мелкие детали, зависящие от реализации. Просто хотелось бы знать основные принципы.

Что касается моего второго вопроса - "Почему, например, int** не приводится к void** неявно?" - то мне часто приходится делать такое приведение при работе с Carbon framework (Mac OSX).
361
28 февраля 2007 года
Odissey_
661 / / 19.09.2006
Пересмотрел все написанное.
Вообщем да, ваши коллеги правы (причем и те и другие).
И так имеем.
Test((VoidPtr)iPtr) - не lvalue.
Test((VoidPtr&)iPtr) - lvalue.
Дело в том, что преобразования не к ссылочным типам считается rvalue. Соотвественно поэтому ошибка.
Про определенние rvalue и lvalue (и еще много про что) - здесь.

//==== Add
Так как ссылка по сути является константным указателем, то иннициализироваться она может только один раз, при объявлении. Иннициализация разрешена только lvalue (объектом имеющим адрес в памяти).
И насчет первого вашего примера.
Код:
typedef int* VoidPtr;
void Test(VoidPtr &)
{}

int main(int argc, char* argv[])
{
 int i = 0;
 int *iPtr = &i;
 int *& RefPtr = iPtr; // корректно

 Test((VoidPtr)iPtr); // не корректно

 return 0;
}
20K
02 марта 2007 года
sja
22 / / 08.01.2007
Очень хорошо про ссылки и указатели пишет Бьерн Страуструп.
Рекомндую всем!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог