Константность объекта и мембер-указатель
От: johny5 Новая Зеландия
Дата: 10.09.07 13:26
Оценка:
Интересно, почему константность объекта передаётся только на константность указателя но не на объект, на который указатель указывает.

struct Test
{
    int* value;
};


void f()
{
    const Test t;

    *t.value = 0;
}


Выглядит как брешь в константности.
Почему так было сделано?

Спасибо.
Re: Константность объекта и мембер-указатель
От: jazzer Россия Skype: enerjazzer
Дата: 10.09.07 13:33
Оценка:
Здравствуйте, johny5, Вы писали:

J>Интересно, почему константность объекта передаётся только на константность указателя но не на объект, на который указатель указывает.


J>
J>struct Test
J>{
J>    int* value;
J>};


J>void f()
J>{
J>    const Test t;

J>    *t.value = 0;
J>}
J>


J>Выглядит как брешь в константности.

J>Почему так было сделано?

потому что указатель и то, на что он ссылкается — вещи не обосо связанные.
у тебя тип, к оторому применяется const — это указатель (т.е. после этого ты не сможешь его перенацелить на другой объект). К константности указуемого объекта это не имеет никакого отношения.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Константность объекта и мембер-указатель
От: johny5 Новая Зеландия
Дата: 10.09.07 14:40
Оценка:
>потому что указатель и то, на что он ссылкается — вещи не обосо связанные.
>у тебя тип, к оторому применяется const — это указатель (т.е. после этого ты не сможешь его перенацелить на другой объект). К константности указуемого объекта это не имеет никакого отношения.

Это понятно, я немного о другом.


struct Test
{
    int a;
};

void f()
{
    const Test t;

    t.a = 5;  //низя
}


и

struct Test
{
    int* a;  //просто другой вид хранения значения int
};

void f()
{
    const Test t;

    *t.a = 5;  //можно
}


с чего собственно? Почему такая разница?

Константность объекта подрузамевает константность всех его внутренностей. Не должно быть разницы, представлены они через указатель или по значению.
Re[3]: Константность объекта и мембер-указатель
От: jazzer Россия Skype: enerjazzer
Дата: 10.09.07 15:27
Оценка: 1 (1)
Здравствуйте, johny5, Вы писали:

>>потому что указатель и то, на что он ссылкается — вещи не обосо связанные.

>>у тебя тип, к оторому применяется const — это указатель (т.е. после этого ты не сможешь его перенацелить на другой объект). К константности указуемого объекта это не имеет никакого отношения.

J>Константность объекта подрузамевает константность всех его внутренностей. Не должно быть разницы, представлены они через указатель или по значению.


Указатель и является внутренностями. Но не указуемое.

И вообще, что есть внутренность — вопрос скользкий.
Указатель — это не просто другой вид хранения.
Это — ссылочный тип, и то, что он ссылается на какой-то другой тип, означает лишь то, какой тип ты получишь в результате его разыменования. Т.е. единственная операция, которая обращается непосредственно к указуемому — это разыменование. Все остальные операции относятся именно к самому указателю как к ссылочному типу, а именно: любое изменение указателя (присваивание, инкремент и т.п.) означает перенацеливание.
И когда ты говоришь, что конкретный указатель является константой — ты просто гововришь, что все операции, которые его изменяют (т.е. перенацеливают), запрещены.

Разыменование указателя, очевидно, к изменяющим указатель операциям никак не относится.

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

Единственная проблема (это так, навскидку) — что должно в результате давать снятие константности с указателя — неконстантный указатель на константу или на не-константу?
И чем же тогда является указатель на константу?
Или разрешим только два вида указателей — константный указатель на константу и неконстантный на неконстанту? Имхо, не слишком разумно.

Имхо, текущий подход наиболее логичен.

P.S. Если очень хочется протянуть const на все уровни многовложенного типа, воспользуйся boost::mpl.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Константность объекта и мембер-указатель
От: Roman Odaisky Украина  
Дата: 10.09.07 16:54
Оценка:
Здравствуйте, johny5, Вы писали:

J>Интересно, почему константность объекта передаётся только на константность указателя но не на объект, на который указатель указывает.


J>
J>struct Test
J>{
J>    int* value;
J>};


J>void f()
J>{
J>    const Test t;

J>    *t.value = 0;
J>}
J>


J>Выглядит как брешь в константности.

J>Почему так было сделано?

Потому что int * — просто четыре (например) байта, которые можно интерпретировать как адрес чего-нибудь в памяти. Эти четыре байта менять нельзя, а то, куда они указывают, здесь ни при чем.

Сравни int const * и int * const.
До последнего не верил в пирамиду Лебедева.
Re[3]: Константность объекта и мембер-указатель
От: remark Россия http://www.1024cores.net/
Дата: 10.09.07 17:27
Оценка:
Здравствуйте, johny5, Вы писали:

J>
J>struct Test
J>{
J>    int a;
J>};

J>void f()
J>{
J>    const Test t;

J>    t.a = 5;  //низя
J>}
J>


J>и


J>
J>struct Test
J>{
J>    int* a;  //просто другой вид хранения значения int
J>};

J>void f()
J>{
J>    const Test t;

J>    t.a = 0;  //тоже низя
J>}
J>


Всё консистентно


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Константность объекта и мембер-указатель
От: Кодт Россия  
Дата: 10.09.07 17:54
Оценка: 4 (2) +2
Здравствуйте, johny5, Вы писали:

J>Интересно, почему константность объекта передаётся только на константность указателя но не на объект, на который указатель указывает.

J>Выглядит как брешь в константности.
J>Почему так было сделано?

Эта штука называется поверхностной константностью (shallow constness). Известно ещё по феодализму: вассал моего вассала — не мой вассал.
Точно так же, как и копирование и уничтожение указателей — поверхностное.
int* p1 = new int(5);
int* p2 = p1;
*p2 = 7;
assert(*p1 == 7);

При глубоком (deep) копировании — были бы два разных объекта
А при глубоком уничтожении — в момент выхода из области видимости был бы вызван деструктор объекта.

Поверхностное поведение является базовым.
Ведь, во-первых, никто не говорил, что указуемое всегда принадлежит указателю.
И во-вторых, глубину можно реализовать руками. А вот поверхностность — если глубина обеспечивается компилятором — без хака уже не получится.

А в тех случаях, когда тебе нужно реализовать глубокую константность или глубокое копирование — берёшь и пишешь адаптер.
Например,
template<class V>
class deep_const_ptr
{
    V* m_ptr;
public:
    deep_const_ptr() {} // или инициализируешь NULL-ом
    deep_const_ptr(V* p) : m_ptr(p) {}
    deep_const_ptr& operator=(V* p) { m_ptr = p; return *this; }
    
    V* operator->() { return m_ptr; }
    V const* operator() const { return m_ptr; }
    V& operator*() { return *m_ptr; }
    V const& operator() const { return *m_ptr; }
};

Но, используя этот класс вместо голого указателя, ты подчёркиваешь, что указуемое находится в более тесной связи с этим указателем (и объектом, чьим членом указатель является).
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: Константность объекта и мембер-указатель
От: Erop Россия  
Дата: 11.09.07 13:27
Оценка: 1 (1)
Здравствуйте, johny5, Вы писали:

J>Выглядит как брешь в константности.

А const_cast не выглядит, как брешь? ИМХО
Автор: Erop
Дата: 04.09.07
брешь там или не брешь зависит от семантики класса. Надо управлять явно -- управляй явно, через адаптеры, через умные указатели и т. д.

J>Почему так было сделано?

Я думаю, что так было сделано, потому что так логичнее реализация. Грубо говоря такой подход гарантирует истинность следующего утверждения: "бинарное представление константного POD-типа, и только ононе может изменяться".
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.