GESP 六级 · GESP 202603 C++ 六级 第 2 题

选择题 · 答案 B · 考点:函数

← 整套速查表 GESP 六级 全部真题

题目

下列代码中, s1->draw(); 和 s2->draw(); 输出不同结果的主要原因是( )。

class Shape {
public:
    virtual void draw() {
        cout << "绘制图形" << endl;
    }

    virtual ~Shape() {}
};

class Circle : public Shape {
public:
    void draw() override {
        cout << "绘制圆形" << endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() override {
        cout << "绘制矩形" << endl;
    }
};

int main() {
    Shape* s1 = new Circle();
    Shape* s2 = new Rectangle();

    s1->draw();
    s2->draw();

    delete s1;
    delete s2;
    return 0;
}
答案:B

考点

函数

解题思维

C++类:构造函数(对象创建时调用)、析构函数(对象销毁时调用)、虚函数(实现多态)。构造函数不能为虚。

常见错误

构造函数不能是虚函数(虚表在构造函数完成后才建立)。析构函数可以且通常应该为虚函数(防止内存泄漏)。

详细解析(节选)

【考点】虚函数机制|动态联编|多态继承

看到题先定位基类Shape的draw()是否加了virtual——答案在代码第一行就写死了。然后对比选项:A说"是普通成员函数",但代码明明写了virtual;C说"public继承",虽然对,但不是差异原因;D说"指针变量名不同",这跟函数行为无关。只有B"Shape中的draw()被声明为虚函数"直接解释了为什么调用时能区分对象实际类型。

陷阱在于"继承≠多态"。很多学生选了C,以为只要继承就能多态,却忘了基类必须声明virtual。题目里Shape的draw()明明写了virtual,如果它没写,那s1->draw()就会直接调用基类版本,输出"绘制图形",和s2->draw()一样。A选项是偷换概念,把虚函数说成普通函数;D选项是抓不住语义,指针名不同不影响调用逻辑。最阴险的是C——它看似正确,却忽略了"虚表"的存在,只背了"继承"没背"虚函数"。

如果把Shape中的virtual去掉,s1->draw()和s2->draw()都会调用基类版本,答案就变成A了。如果把Circle和Rectangle的draw()改成static,那也不会有多态,答案会变成C。如果把s1改成Circle*、s2改成Rectangle*,那直接静态绑定,答案会变D。刷到类似题先问:这题考的是"虚函数"还是"继承"还是"指针类型"?

同考点真题

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断