定义一个document类,有数据成员name,从document派生出book类,增加数据成员pagecount。在构造函数和析构函数中输出信息,观察基类与派生类的构造函数和析构函数的调用顺序。
时间: 2023-05-31 15:19:48 浏览: 269
### 回答1:
定义一个document类,有数据成员name,表示文档名称。从document派生出book类,增加数据成员pagecount,表示书籍页数。在构造函数和析构函数中输出信息,观察基类与派生类的构造函数和析构函数的调用顺序。
代码如下:
```c++
#include <iostream>
#include <string>
using namespace std;
class document {
public:
document(const string& name) : name_(name) {
cout << "document constructor called: " << name_ << endl;
}
virtual ~document() {
cout << "document destructor called: " << name_ << endl;
}
protected:
string name_;
};
class book : public document {
public:
book(const string& name, int pagecount) : document(name), pagecount_(pagecount) {
cout << "book constructor called: " << name_ << ", " << pagecount_ << " pages" << endl;
}
~book() {
cout << "book destructor called: " << name_ << ", " << pagecount_ << " pages" << endl;
}
private:
int pagecount_;
};
int main() {
book b("The Lord of the Rings", 1178);
return ;
}
```
输出结果如下:
```
document constructor called: The Lord of the Rings
book constructor called: The Lord of the Rings, 1178 pages
book destructor called: The Lord of the Rings, 1178 pages
document destructor called: The Lord of the Rings
```
可以看到,先调用基类的构造函数,再调用派生类的构造函数;先调用派生类的析构函数,再调用基类的析构函数。
### 回答2:
对于这道题目,我们首先需要按照要求定义一个document类,并在其构造函数和析构函数中输出相应的信息。代码如下:
```c++
#include <iostream>
using namespace std;
class document {
public:
string name;
document(string n) : name(n) {
cout << "Constructing document " << name << endl;
}
~document() {
cout << "Destructing document " << name << endl;
}
};
```
接着,我们需要从document类派生出一个book类,并增加一个名为pagecount的数据成员。在构造函数和析构函数中,我们同样输出相应的信息。代码如下:
```c++
class book : public document {
public:
int pagecount;
book(string n, int pc) : document(n), pagecount(pc) {
cout << "Constructing book " << name << " with " << pagecount << " pages" << endl;
}
~book() {
cout << "Destructing book " << name << " with " << pagecount << " pages" << endl;
}
};
```
在上述代码中,我们使用了派生类构造函数的初始化列表来调用基类构造函数,并传递参数name。同时,我们还增加了pagecount参数,并将它输出到控制台上。
最后,为了观察基类与派生类的构造函数和析构函数的调用顺序,我们可以在主函数中创建一个book对象,然后在其作用域结束时销毁它。代码如下:
```c++
int main() {
book myBook("C++ Primer", 1000);
return 0;
}
```
运行程序后,我们可以得到以下输出结果:
```
Constructing document C++ Primer
Constructing book C++ Primer with 1000 pages
Destructing book C++ Primer with 1000 pages
Destructing document C++ Primer
```
从输出结果可以看出,在创建book对象时,先调用了document类的构造函数,然后调用了book类的构造函数。在销毁book对象时,先调用了book类的析构函数,然后调用了document类的析构函数。这表明在继承关系中,派生类的构造函数和析构函数会优先于基类的构造函数和析构函数执行。
### 回答3:
定义一个document类,可以包含下面的数据成员:
```cpp
class document {
protected:
std::string name;
public:
document(std::string _name): name(_name) {
std::cout << "Constructing document " << name << std::endl;
}
~document() {
std::cout << "Destructing document " << name << std::endl;
}
};
```
定义一个book类,从document类派生,增加数据成员pagecount:
```cpp
class book : public document {
protected:
int pagecount;
public:
book(std::string _name, int _pagecount): document(_name), pagecount(_pagecount) {
std::cout << "Constructing book " << name << " with " << pagecount << " pages" << std::endl;
}
~book() {
std::cout << "Destructing book " << name << std::endl;
}
};
```
上面的构造函数和析构函数中都输出了信息,方便我们观察构造函数和析构函数的调用顺序。
我们可以进行一些测试来观察基类与派生类的构造函数和析构函数的调用顺序:
```cpp
int main() {
document* doc1 = new document("Document 1");
std::cout << std::endl;
document* doc2 = new book("Book 1", 100);
std::cout << std::endl;
delete doc1;
std::cout << std::endl;
delete doc2;
std::cout << std::endl;
book book1("Book 2", 200);
std::cout << std::endl;
return 0;
}
```
我们首先创建一个document对象,然后创建一个book对象,将指向book对象的指针赋给一个document指针。接着我们删除doc1和doc2,最后创建一个book对象。
程序输出如下:
```
Constructing document Document 1
Constructing document Book 1
Constructing book Book 1 with 100 pages
Destructing document Document 1
Destructing book Book 1
Destructing document Book 1
Constructing document Book 2
Constructing book Book 2 with 200 pages
Destructing book Book 2
Destructing document Book 2
```
我们可以看到,创建document对象时只调用了document的构造函数,删除document对象时只调用了document的析构函数。
创建book对象时,首先调用document的构造函数,然后再调用book的构造函数。删除book对象时,首先调用book的析构函数,然后再调用document的析构函数。
在创建book1对象时,也是先调用document的构造函数,然后再调用book的构造函数。程序结束时,会先调用book的析构函数,然后再调用document的析构函数。
综上,我们可以看到,在派生类的构造函数和析构函数中,都会先调用基类的构造函数和析构函数。而在创建对象时,先调用基类的构造函数,再调用派生类的构造函数;在删除对象时,先调用派生类的析构函数,再调用基类的析构函数。
阅读全文