#872. 面向对象练习

面向对象练习

一、选择题

1.下列关于类的说法,错误的是( )。

{{ select(1) }}

  • 构造函数不能声明为虚函数,但析构函数可以
  • 函数参数如声明为类的引用类型,调用时不会调用该类的复制构造函数
  • 静态方法属于类而不是某个具体对象,因此推荐用 类名::方法(...) 调用
  • 不管基类的析构函数是否是虚函数,都可以通过基类指针/引用正确删除派生类对象

2.假设变量 veh 是类 Car 的一个实例,我们可以调用 veh.move(),是因为面向对象编程有( )性质。

class Vehicle {
private:
    string brand;

public:
    Vehicle(string b) : brand(b) {}

    void setBrand(const string& b) { brand = b; }
    string getBrand() const { return brand; }

    void move() const {
        cout << brand << " is moving..." << endl;
    }
};

class Car : public Vehicle {
private:
    int seatCount;

public:
    Car(string b, int seats) : Vehicle(b), seatCount(seats) {}

    void showInfo() const {
        cout << "This car is a " << getBrand()
             << " with " << seatCount << " seats." << endl;
    }
};

{{ select(2) }}

  • 继承
  • 封装
  • 多态
  • 链接

3.下面代码中 v1v2 调用了相同接口 move(),但输出结果不同,这体现了面向对象编程的( )特性。

class Vehicle {
private:
    string brand;

public:
    Vehicle(string b) : brand(b) {}

    void setBrand(const string& b) { brand = b; }
    string getBrand() const { return brand; }

    virtual void move() const {
        cout << brand << " is moving..." << endl;
    }
};

class Car : public Vehicle {
private:
    int seatCount;

public:
    Car(string b, int seats) : Vehicle(b), seatCount(seats) {}

    void showInfo() const {
        cout << "This car is a " << getBrand()
             << " with " << seatCount << " seats." << endl;
    }

    void move() const override {
        cout << getBrand() << " car is driving on the road!" << endl;
    }
};

class Bike : public Vehicle {
public:
    Bike(string b) : Vehicle(b) {}

    void move() const override {
        cout << getBrand() << " bike is cycling on the path!" << endl;
    }
};

int main() {
    Vehicle* v1 = new Car("Toyota", 5);
    Vehicle* v2 = new Bike("Giant");

    v1->move();
    v2->move();

    delete v1;
    delete v2;
    return 0;
}

{{ select(3) }}

  • 继承 (Inheritance)
  • 封装 (Encapsulation)
  • 多态 (Polymorphism)
  • 链接 (Linking)

4.关于虚函数描述错误的是( )。

{{ select(4) }}

  • 虚函数用于支持运行时多态
  • 通过基类指针调用虚函数会根据对象实际类型决定调用版本
  • 构造函数可以声明为虚函数
  • 基类析构函数常声明为虚函数以避免资源泄漏

5.执行如下代码,会输出 钢琴:叮咚叮咚吉他:咚咚当当 。这体现了面向对象编程的( )特性。

class Instrument {
public:
    virtual void play() {
        cout << "乐器在演奏声音" << endl;
    }

    virtual ~Instrument() {}
};

class Piano : public Instrument {
public:
    void play() override {
        cout << "钢琴:叮咚叮咚" << endl;
    }
};

class Guitar : public Instrument {
public:
    void play() override {
        cout << "吉他:咚咚当当" << endl;
    }
};

int main() {
    Instrument* instruments[2];
    instruments[0] = new Piano();
    instruments[1] = new Guitar();

    for (int i = 0; i < 2; ++i) {
        instruments[i]->play();
    }

    for (int i = 0; i < 2; ++i) {
        delete instruments[i];
    }
    return 0;
}

{{ select(5) }}

  • 继承
  • 封装
  • 多态
  • 链接

6.关于以下代码,说法正确的是( )。

class Instrument {
public:
    void play() {
        cout << "乐器在演奏声音" << endl;
    }

    virtual ~Instrument() {}
};

class Piano : public Instrument {
public:
    void play() override {
        cout << "钢琴:叮咚叮咚" << endl;
    }
};

class Guitar : public Instrument {
public:
    void play() override {
        cout << "吉他:咚咚当当" << endl;
    }
};

int main() {
    Instrument* instruments[2];
    instruments[0] = new Piano();
    instruments[1] = new Guitar();

    for (int i = 0; i < 2; ++i) {
        instruments[i]->play();
    }

    for (int i = 0; i < 2; ++i) {
        delete instruments[i];
    }
    return 0;
}

{{ select(6) }}

  • 执行代码会输出两行,内容分别为:钢琴:叮咚叮咚吉他:咚咚当当
  • 执行代码会输出两行,内容分别为:乐器在演奏声音乐器在演奏声音
  • 代码编译出现错误
  • 代码运行出现错误

7.下列关于 C++ 中类的描述,正确的是( )。

{{ select(7) }}

  • 如果类没有用户声明的构造函数,那么编译器会隐式声明一个默认构造函数
  • 类的析构函数可以被重载,一个类可以有多个析构函数
  • 类中的所有成员都必须声明为 public
  • 类和结构体在 C++ 中没有区别,包括默认访问权限也相同

二、判断题

8.以下代码中,构造函数被调用的次数是1次。

class Test {
public:
    Test() { cout << "T "; }
};
int main() {
    Test a;
    Test b = a;
}

{{ select(8) }}

  • 正确
  • 错误

9.当基类可能被多态使用,其析构函数应该声明为虚函数。

{{ select(9) }}

  • 正确
  • 错误

10.面向对象编程中,封装是指将数据和操作数据的方法绑定在一起,并对外隐藏实现细节。

{{ select(10) }}

  • 正确
  • 错误

11.下面定义了一个表示二维坐标点的类 Point , 并提供了一个带参数的构造函数,但第 ② 行 Point b; 会调用编译器自动生成的默认构造函数,将 b.x 和 b.y 被初始化为 0.0,程序可以正常编译运行。

class Point {
public:
    double x, y;
    Point(double px, double py) : x(px), y(py) {}
    void print() {
        cout << "(" << x << ", " << y << ")";
    }
};
int main() {
    Point a(3.0, 4.0); // ①
    Point b; // ②
    a.print();
}

{{ select(11) }}

  • 正确
  • 错误

12.C++ 中的继承支持单继承和多继承,但子类无法直接访问父类的私有成员。

{{ select(12) }}

  • 正确
  • 错误