C++-明确何时以及如何调用析构函数

C++ - Clarifying when and how destructors are called

本文关键字:调用 析构函数 何调用 何时 C++-      更新时间:2023-10-16

所以我下面有一个完整的程序,它创建Book对象,初始化它们,并打印在程序执行过程中创建或销毁的任何构造函数/析构函数。

我已经运行了我的代码(并粘贴了下面的输出(,我很难理解如何调用析构函数。所以我知道构造函数的销毁顺序与它们的创建顺序相反。但我不明白为什么其中四个析构函数语句的id为4。我假设其中一个来自"对副本构造函数的显式调用",另一个来自于"从第5本书中声明和初始化第6本书",而另一个则来自于"声明和初始化书1到4"的第一部分。但我很困惑4的额外id是从哪里来的?

此外,我想知道为什么没有为创建默认ctor:0的"声明书5"部分打印"--dtor:0"。

如果有任何澄清,我将不胜感激!

main.cc:

#include <iostream>
#include <string>
using namespace std;
#include "Book.h"

void func1(Book);
void func2(Book&);

int main()
{
cout<<endl<<"Declaring and initializing books 1 to 4..."<<endl;
Book b1(1, "Ender's Game", "Orson Scott Card");
Book b2(2, "Dune", "Frank Herbert");
Book b3(3, "Foundation", "Isaac Asimov");
Book b4(4, "Hitch Hiker's Guide to the Galaxy", "Douglas Adams");
cout<<endl<<"Declaring book 5..."<<endl;
Book b5;
b5.print();
cout<<endl<<"Assigning book 4 to 5..."<<endl;
b5 = b4;
b5.print();
cout<<endl<<"Declaring and initializing book 6 from book 5..."<<endl;
Book b6 = b5;
b6.print(); 
cout<<endl<<"Calling func1()..."<<endl;
func1(b1);
cout<<endl<<"Calling func2()..."<<endl;
func2(b2);
cout<<endl<<"Explicit call to copy constructor..."<<endl;
Book b7(b6);

cout << endl << endl;
return 0;
}
void func1(Book b)
{
b.print();
}
void func2(Book& b)
{
b.print();
}

book.cc:

#include <iostream>
#include <string>
using namespace std;
#include "Book.h"
Book::Book(int i, string t, string a)
{
cout<<"-- default ctor:  "<< i <<endl;
id     = i;
title  = t;
author = a;
}
Book::Book(const Book& other)
{
id     = other.id;
title  = other.title;
author = other.author;
cout<<"-- copy ctor:  "<< id <<endl;
}

Book::~Book()
{
cout<<"-- dtor:  "<< id <<endl;
}
void Book::print()
{
cout<<"** "<< title <<" by "<<author<<endl;
}

book.h:

#ifndef BOOK_H
#define BOOK_H
#include <string>
using namespace std;
class Book
{
public:
Book(int=0, string="Unknown", string="Unknown");
Book(const Book&);
~Book();
void print();
private:
int id;
string title;
string author;
};
#endif

输出:

Declaring and initializing books 1 to 4...
-- default ctor:  1
-- default ctor:  2
-- default ctor:  3
-- default ctor:  4
Declaring book 5...
-- default ctor:  0
** Unknown by Unknown
Assigning book 4 to 5...
** Hitch Hiker's Guide to the Galaxy by Douglas Adams
Declaring and initializing book 6 from book 5...
-- copy ctor:  4
** Hitch Hiker's Guide to the Galaxy by Douglas Adams
Calling func1()...
-- copy ctor:  1
** Ender's Game by Orson Scott Card
-- dtor:  1
Calling func2()...
** Dune by Frank Herbert
Explicit call to copy constructor...
-- copy ctor:  4

-- dtor:  4
-- dtor:  4
-- dtor:  4
-- dtor:  4
-- dtor:  3
-- dtor:  2
-- dtor:  1

我不明白为什么四个析构函数语句的id为4

因为您在语句中将b4分配给b5

b5 = b4;

然后复制构造b6 = b5;b7(b6);,它们中的每一个都具有id=4,所以析构函数打印

-- dtor: 4

此外,我想知道为什么没有为创建默认ctor:0的"声明书5"部分打印"--dtor:0"。

因为创建Book b5;id=0,但当代码将b4分配给b5时,id变为4,因此没有打印"--dtor:0"。