Почему программа из учебного примера не завершается аварийно?
От: Lanjeron32  
Дата: 09.12.18 18:39
Оценка:
Всем привет. Я новичок в C++ (прошу сильно не пинать за нубские вопросы).

Изучаю C++ по книге. Дошел до примера класса с копирующим конструктором:

#include <iostream>
#include <string.h>
using namespace std;
class MyString
{
   private:
      char* buffer;
   public:
      MyString(const char* initString) //конструктор
      {
          buffer = nullptr;
          cout << "Вызов конcтруктора по умолчанию" << endl;
          if (initString != nullptr)
          {
               buffer = new char[strlen(initString) + 1];
               strcpy(buffer, initString);

               cout << "buffer указывает на: " << hex;
               cout << (unsigned int*)buffer << endl;
          }
      }

      MyString(const MyString& copySource) //Копирующий конструктор
      {
          buffer = nullptr;
          cout << "Вызов копирующего конструктора" << endl;
          if (copySource.buffer != nullptr)
          {
              // Выделение собственного буфера
              buffer = new char[strlen(copySource.buffer) + 1];

              // Глубокое копирование исходного буфера в целевой
              strcpy(buffer, copySource.buffer);

              cout << "buffer указывает на: " << hex;
              cout  <<  (unsigned int*)buffer << endl;
          }
      }

      // Деструктор
      ~MyString()
      {
          cout << "Вызов деструктора" << endl;
          delete[] buffer;
      }

      int GetLength()
      {  return strlen(buffer); }

      const char* GetString()
      { return buffer; }
 };

void UseMyString(MyString str)
{
    cout << "Длина buffer в MyString равна " << dec;
    cout << str.GetLength() << " символам" << endl;

    cout << "buffer содержит: " << str.GetString() << endl;
    return;
}

int main()
{
    MyString sayHello("Hello from String Class");
    UseMyString(sayHello);

    int quit = 0;
    cin >> quit;
    return 0;
}

Этот пример при чтении книги полностью понятен. Показано, что если не будет копирующего конструктора, то функция UseMyString() будет выполнять поверхностное копирование экземпляра класса MyString. В результате будут созданы два указателя buffer на одну и ту же область памяти, а затем при выходе из main() произойдет аварийное завершение, потому что ~MyString() с delete[] в нем будет вызван дважды — при выходе из UseMyString() и при выходе из main(). В книге даже приведен скриншот аварийного завершения для среды Visual Studio.

Однако я этот пример изучал в среде Qt, и если закомментировать весь копирующий конструктор, то программа не падает. При компиляции была только парочка небольших предупреждений, а так все работает нормально. Деструктор вызывается дважды, как и должно быть, но падения не происходит.
Что это может быть? Может, Qt в отличие от Visual Studio создает какой-то копирующий конструктор по умолчанию? Если да, то можно ли его как-то увидеть?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.