题目
在C++中,以下程序输出正确的是()#includeclass Base {public:Base() ( std::cout << "P"; )~Base() ( std::cout << "p"; )};class Sub : public Base {public:Sub() ( std::cout << "S"; )~Sub() ( std::cout << "s"; )private:Base b;};int main() {Sub s;return 0;}A SPPppsB PPSppsC PPSspp
在C++中,以下程序输出正确的是()
#include
class Base {
public:
Base() { std::cout << "P"; }
~Base() { std::cout << "p"; }
};
class Sub : public Base {
public:
Sub() { std::cout << "S"; }
~Sub() { std::cout << "s"; }
private:
Base b;
};
int main() {
Sub s;
return 0;
}
A SPPpps
B PPSpps
C PPSspp
题目解答
答案
在`Sub`对象`s`的创建过程中:
1. 先调用`Base`的构造函数(继承部分),输出`"P"`。
2. 再调用`Base b`的构造函数(成员对象),输出`"P"`。
3. 最后调用`Sub`的构造函数,输出`"S"`。
销毁时:
1. 先调用`Sub`的析构函数,输出`"s"`。
2. 再调用`Base b`的析构函数,输出`"p"`。
3. 最后调用`Base`的析构函数(继承部分),输出`"p"`。
综上,输出为`"PPSspp"`。
答案:C. PPSspp
解析
考查要点:本题主要考查C++中构造函数和析构函数的调用顺序,特别是涉及继承和成员对象时的执行顺序。
解题核心思路:
- 构造函数调用顺序:
- 派生类对象构造时,基类子对象的构造函数最先执行。
- 然后按声明顺序初始化成员对象。
- 最后执行派生类自身的构造函数。
- 析构函数调用顺序:
- 派生类的析构函数最先执行。
- 然后是成员对象的析构函数。
- 最后是基类子对象的析构函数。
破题关键点:
- 明确区分基类子对象(继承部分)和成员对象(
private: Base b)的构造顺序。 - 注意析构顺序与构造顺序严格相反。
构造阶段分析
- 基类子对象构造:
Sub继承自Base,因此创建Sub对象s时,首先调用基类子对象的构造函数,输出P。 - 成员对象构造:
Sub类中声明了成员Base b,因此接下来调用该成员对象的构造函数,输出第二个P。 - 派生类构造函数:
最后调用Sub自身的构造函数,输出S。
构造阶段输出:P P S
析构阶段分析
- 派生类析构函数:
对象s销毁时,首先调用Sub的析构函数,输出s。 - 成员对象析构:
然后销毁成员b,调用其析构函数,输出p。 - 基类子对象析构:
最后销毁基类子对象,调用其析构函数,输出最后一个p。
析构阶段输出:s p p
最终输出
将构造和析构的输出合并,得到完整结果:PPSspp。