Является ли const_cast для этого указателя неопределенным поведением?

У меня есть следующий код С++. Я могу скомпилировать его с помощью g++ 4.9.2 на машине с Linux. Затем, когда я запускаю его, он печатает 10. Кажется, что новый объект создается и назначается указателю, созданному с помощью const_cast в конструкторе по умолчанию. Утечек памяти нет (проверил с помощью valgrind). Это какое-то неопределенное поведение или это законно?

#include <iostream>

using namespace std;

class A
{
   public:
      A() : x(0)
      {
         A *tmp = const_cast<A*>(this);
         *tmp = A(10);
      }

      A(int x)
      {
         this->x = x;
      }

      int getX() const
      {
         return x;
      }

   private:
      int x;
};

int main()
{
   A a;

   cout << a.getX() << endl;

   return 0;
}

person bercik    schedule 14.03.2017    source источник
comment
this не должно быть константой в конструкторе, поэтому константное приведение ничего не делает.   -  person tkausl    schedule 14.03.2017
comment
Утечек памяти нет — надеюсь, что нет, так как во всем этом исходнике нет ни одного динамического выделения. Несмотря на это, осмелюсь спросить, почему вы хотите const_fast и this в конструкторе?   -  person WhozCraig    schedule 14.03.2017
comment
const_cast не имеет к этому никакого отношения. Вы могли бы просто сделать *this = A(10). Или x = 10 :-)   -  person Bo Persson    schedule 14.03.2017


Ответы (1)


const_cast не имеет ничего общего с вашим поведением. Ваш код может быть упрощен до следующего:

  A() : x(0)
  {
     *this = A(10);
  }

Итак, здесь происходит следующее, если мы хотим создать объект с помощью конструктора по умолчанию:

  1. перед телом конструктора Память для объекта this зарезервирована.
  2. x(0) 0 назначается члену x группы this.
  3. A(10) Новый (безымянный) объект класса A создается с помощью конструктора A(int). Этот новый член объекта x имеет значение 10.
  4. this= Здесь безымянный объект назначается (с помощью автоматически сгенерированного оператора копирования, который является полевым) *this. Таким образом, значение члена x из this становится 10.
  5. после этой строки Временный безымянный объект уничтожается.
  6. this возвращается.

Это совершенно законное и ожидаемое поведение.

person alexeykuzmin0    schedule 14.03.2017
comment
Спасибо за объяснение - person bercik; 14.03.2017