Вызовы функций C ++, почему используется деструктор? - PullRequest
0 голосов
/ 20 января 2019

Я пытаюсь лучше понять вызовы функций в C ++.У меня есть следующий код:

class A{ 
  public:
    A() { cout << "hello\n"; }
    A(const A& obj) { cout << "world\n"; }
    ~A() { cout << "bye\n"; }

  virtual void print() { cout << "a\n"; }
};

A foo(A aobj)
{
    aobj.print();
    return aobj;
}

int main(){
  A a,b,c;
  foo(a);
  system("pause");
  return 0;
}

Вывод:

hello //from calling A's default constructor

hello

hello

world //because we pass 'a' by value in funtion foo so the copy constructor is used


a

world //because foo returns by value so the copy constructor is used again

bye //?

bye //?

Может кто-нибудь объяснить, почему деструктор вызывается дважды в конце?Это из-за двух вызовов конструкторов копирования?

Спасибо за потраченное время!

Ответы [ 3 ]

0 голосов
/ 20 января 2019

Попробуйте это:

class A {
       public:
    A() { cout << "Default ctor → A::A()\n"; }
    ~A() { cout << "Default dtor → A::~A()\n"; }

    A(const A&) {
        cout << "Copy ctor → A::A(const A& rhs)\n";
    }
    A& operator=(const A& rhs) {
        cout << "Copy operator= → A& A::operator=(const A& rhs)\n";
        return *this;
    }

    A(const A&&) {
        cout << "Move ctor → A::A(const A&& rhs)\n";
    }
    A& operator=(const A&& rhs) {
        cout << "Move operator= → A& A::operator=(const A&& rhs)\n";
        return *this;
    }
};

Также получите копию Effective Modern C ++ и прочитайте Элемент 17: Понимание генерации специальных функций-членов.

0 голосов
/ 20 января 2019

Создано 5 объектов, поэтому будет выведено 5 "пока".

Однако только 2 объекта выходят из области видимости и разрушаются до вашего вызоваsystem("pause") (2 объекта, созданные foo()).Остальные 3 объекта выходят из области видимости и разрушаются после вызова system("pause").Таким образом, у вас может не быть возможности увидеть эти 3 «пока», если окно консоли закрывается при выходе из приложения.

Вы можете заставить эти 3 объекта выйти из области видимости быстрее, введя другой более короткий срокобласть, в которой они могут жить, например:

int main(){
    {
    A a,b,c;
    foo(a);
    }
    system("pause");
    return 0;
}

Или вот так:

void doIt(){
    A a,b,c;
    foo(a);
}

int main(){
    doIt();
    system("pause");
    return 0;
}

Теперь все 5 объектов выйдут из области видимости и будут уничтожены до звонок на system("pause").

0 голосов
/ 20 января 2019

"пока" печатается 5 раз, потому что ~A() также вызывается 5 раз. Для объектов a, b, c деструктор называется единицей. Затем, когда вы передаете a по значению, в foo создается копия, которая затем уничтожается. Наконец, возвращаемый тип foo является экземпляром A, который уничтожается, когда выполнение переходит на следующую строку. Таким образом, в общей сложности ~A() будет вызвано 5 раз.

Деструктор вызывается в конце срока службы объекта для освобождения памяти, которая использовалась объектом.

...