Почему другое поведение для указателей TYPE* ​​const?

Ниже код имеет дело с указателем TYPE* const.

struct D {
  void Check ()
  {
    D* const p = new D; // 2nd test is "p = 0;"
    cout<<"p = "<<p<<endl;
    (D*&)p = new D;
    cout<<"p = "<<p<<endl; // prints 0, "p = 0;" at declaration
  }
};

int main ()
{
  D o;
  o.Check();
}

Мои вопросы,

  1. Если инициализировать с 0, то хоть приведение типов в следующий раз не сработает. Является ли такое приведение типов неопределенным поведением?
  2. Указатель this тоже типа TYPE* const, тогда почему компилятор не разрешает ту же операцию для this?

person iammilind    schedule 14.04.2011    source источник


Ответы (3)


  1. Как уже говорили другие, это поведение undefined, поскольку оно пытается изменить объект const. Если вы инициализируете его нулем, компилятор может рассматривать его как константу времени компиляции и игнорировать любые попытки его изменить. Или он может сделать что-то совершенно другое.

  2. this не является обычной переменной типа TYPE * const; это выражение rvalue типа TYPE *. Это означает, что его вообще нельзя использовать в качестве цели выражения присваивания или привязывать к непостоянной ссылке.

person Mike Seymour    schedule 14.04.2011
comment
Некоторые компиляторы реализуют this как TYPE *const, что для них достаточно rvalue-y. - person Simon Richter; 17.05.2011
comment
@SimonRichter Какие компиляторы? (Это означает, что они принимают &this.) - person curiousguy; 30.09.2011

Является ли такое приведение типов неопределенным поведением?

Да.

(D*&)p = new D;

Он вызывает неопределенное поведение, поскольку пытается изменить указатель const.

Напомним, что D* const p объявляет переменную p, которая является const указателем на неконстантный D.

person Nawaz    schedule 14.04.2011
comment
Я действительно имел в виду (D*&)p. Но, как вы сказали, он принимает адрес p, я сомневаюсь в этом утверждении. Потому что это не (D*)&p! Я беру ссылку на указатель p. Кроме того, почему он ограничен для this, так как это тоже тот же тип. - person iammilind; 14.04.2011

D* const p = 0;

Это объявление говорит, что p является указателем на D, который является постоянным, то есть он никогда не изменится. Он всегда равен 0.

cout<<"p = "<<p<<endl;

Здесь вы отображаете значение p, которое, как вы ранее сказали, всегда будет равно 0. Угадайте, почему отображается 0!

person Bo Persson    schedule 14.04.2011
comment
Если вы не инициализируете с помощью 0 (как в реальном коде выше), оба cout будут выводить разные ячейки памяти. Если вы инициализируете с помощью 0, то оба cout выведут 0! - person iammilind; 14.04.2011
comment
Это просто потому, что компилятор не может сказать, каким будет адрес. Однако вам не разрешено пытаться изменить его, поскольку вы обещали, что он должен быть постоянным. Это неопределенное поведение, как говорит Наваз. Все может случиться! - person Bo Persson; 14.04.2011