int a[10];
int *сonst p = a; //константный указатель.
p++; // это не возможно;
p = new int; //тоже не возможно
delete p; //а вот тут компилятор (VC6) не ругается.
Re: константный указатель.
От:
Аноним
Дата:
23.09.03 07:16
Оценка:
А почему нет? Ты ж сам указатель никак не меняешь?
Так же вполне можно писать и такое
const int * p = new const int(0);
delete p;
Правда VC такое не скомпилит.
Re: константный указатель.
От:
Аноним
Дата:
23.09.03 07:20
Оценка:
Здравствуйте, SergeyBi, Вы писали:
SB>почему возможно следущее?
SB>простой пример... SB>
SB>int a[10];
SB>int *сonst p = a; //константный указатель.
SB>p++; // это не возможно;
SB>p = new int; //тоже не возможно
SB>delete p; //а вот тут компилятор (VC6) не ругается.
SB>
А что тебя смущает? Ведь все равно ничто не помешает сделать так:
delete не изменяет значение указателя, а просто вызывает operator delete, который в свою очередь освобождаеть память. Если ты посмотришь, то увидишь, после выполнения delete значение указателя не изменяется.
Здравствуйте, SergeyBi, Вы писали:
SB>почему возможно следущее?
SB>простой пример... SB>
SB>int a[10];
SB>int *сonst p = a; //константный указатель.
SB>p++; // это не возможно;
SB>p = new int; //тоже не возможно
SB>delete p; //а вот тут компилятор (VC6) не ругается.
SB>
А почему это не должно быть возможно? От операнда delete expression не требуется того, чтобы он был lvalue. Т.е. фактически можно сказать, что delete работает с копией исходного значения. При этом было ли исходное значение константным или нет — никакой роли не играет.
[]
АТ>А почему это не должно быть возможно? От операнда delete expression не требуется того, чтобы он был lvalue. Т.е. фактически можно сказать, что delete работает с копией исходного значения. При этом было ли исходное значение константным или нет — никакой роли не играет.
А можно сказать, что statement delete принимает свой аргумент по значению, поэтому ему все равно, что l-value, что r-value?
Здравствуйте, MaximE, Вы писали:
M> А можно сказать, что statement delete принимает свой аргумент по M> значению, поэтому ему все равно, что l-value, что r-value?
Это как раз и означает, что операндом delete является rvalue. В случае, если "на вход"
delete подается lvalue, производится соответствующее преобразование lvalue -> rvalue.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Lorenzo_LAMAS, Вы писали:
LL> Если функция принимает объект по значению (UDT), и я передаю ей LL> l-value — тут есть преобразование lvalue to rvalue?
Да. Преобразование lvalue to rvalue — сложный способ назвать факт получения значения (rvalue) объекта (lvalue).
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Lorenzo_LAMAS, Вы писали:
ПК>> Да. Преобразование lvalue to rvalue — сложный способ назвать факт ПК>> получения значения (rvalue) объекта (lvalue).
LL> Да, но ведь сам-то параметр это же lvalue?
int* p = . . .;
delete p;
"Аргумент" delete (то, что мы "передаем") — lvalue. "Параметр" (то, что "получает" delete) — rvalue.
Т.е., мы передали дескриптор ячейки (имя переменной p) — lvalue; а delete нужно значение, которое
хранится в этой ячейке — rvalue. Вот и получается, что из заданной ячейки извлекается значение,
которое там хранится; стандарт это называет преобразованием lvalue to rvalue.
class A
{
public:
A(const A &);
//ctors etcprivate:
int i_;
//etc
};
void fun(A a)
{
}
int main()
{
A b;
fun(a);
return 0;
}
Имеем передачу агрумента, аналогичную A a = b; или A a(b) — т.е. тогда что-то типа const A & copy_ctor_par = b. Как ко всей этой байде применить lvalue-rvalue?
Of course, the code must be complete enough to compile and link.
LL> class A {
LL> public:
LL> A(const A&);
LL> };
LL> void fun(A a) { }
LL> int main()
LL> {
LL> A b;
LL> fun(b);
LL> }
LL>
LL> Имеем передачу агрумента, аналогичную A a = b; или A a(b) — т.е. тогда что-то типа LL> const A & copy_ctor_par = b. Как ко всей этой байде применить lvalue-rvalue?
Не вполне понял, что ты хотел спросить последним предложением, но, тем не менее...
Действительно, инициализация аргумента a осуществляется подобно следующему (copy-initialization):
A a = b;
Соответствующие правила инициализации описаны в 8.5/14. В данном случае инициализация осуществляется
посредством вызова конструктора копирования. Конструктор копирования имеет параметр const A&; соответственно
(назовем параметр конструктора копирования r):
const A& r = b;
Инициализация ссылок описана в 8.5.3/5. Т.к. const A является reference-compatible с A и выражение
инициализатора является lvalue, ссылка привязывается непосредственно к lvalue b. В процессе выполнения
конструктора A::A(const A&), скорее всего, потребуется доступ к членам класса для получения их значений,
что приведет к соответствующим преобразованиям lvalue-to-rvalue.
В результате, в функции f имеем параметр a (lvalue), полученный посредством copy-initialization
из аргумента b (lvalue).
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен