使用基类的指针或引用来访问派生类的成员是一种常见的做法,尤其是在实现多态性时

1.纯虚函数与抽象类的一个例子

#include <iostream>

class Shape {
public:
    virtual void draw() const = 0; // 纯虚函数
    //virtual void draw() = 0;
    virtual ~Shape() {} // 虚析构函数
};

class Circle : public Shape {
private:
    float radius;
public:
    Circle(float r) : radius(r) {}
    void draw() const override {
        std::cout << "Drawing a circle with radius " << radius << std::endl;
    }
};

class Rectangle : public Shape {
private:
    float width;
    float height;
public:
    Rectangle(float w, float h) : width(w), height(h) {}
    void draw() const override {
        std::cout << "Drawing a rectangle with width " << width << " and height " << height << std::endl;
    }
};

int main() {
    // Shape s; // 错误,不能实例化抽象类
    Circle c(5.0);
    Rectangle r(3.0, 4.0);


    //Shape* shapes[] = { &c, &r };
    //for (const auto& shape : shapes) {
    //    shape->draw(); // 多态性,调用正确对象的draw方法
    //}

    //使用抽象类(基类)的指针或引用
    Shape* shape_cptr = &c;
    Shape* shape_rptr = &r;
   
    shape_cptr->draw();
    shape_rptr->draw();

    //使用实例化Circle对象的指针
    Circle* circle_ptr = &c;
    circle_ptr->draw();

    //使用实例化Circle对象本身进行访问
    Rectangle myrectangle(3.0, 4.6);
    myrectangle.draw();




    return 0;
}


2.为什么习惯使用基类的指针或引用?

为什么在有关纯虚函数与抽象类,以及实现动态多态时,常常使用基类的指针或引用来访问派生类的成员是一种常见的做法

答:
在面向对象编程中,使用基类的指针或引用来访问派生类的成员是一种常见的做法,尤其是在实现多态性时。多态性允许不同类型的对象通过共同的接口(通常是基类的接口)进行交互,这样可以编写更通用、更灵活的代码。
使用基类指针或引用的好处包括:

  1. 代码的通用性:你可以编写处理基类指针或引用的代码,这些代码可以与任何派生类对象一起工作,而不需要知道具体的派生类类型。
  2. 接口的稳定性:基类定义了一个稳定的接口,即使派生类发生变化,使用基类指针或引用的代码也不需要改变。
  3. 容器管理:可以使用基类指针的容器(如 std::vectorstd::list)来存储不同类型的派生类对象,这样容器中的元素就可以是多态的。
  4. 运行时绑定:使用指针或引用可以实现运行时多态,这意味着在运行时根据对象的实际类型来调用相应的成员函数。
    在你的代码中,你确实可以直接使用派生类的对象来调用成员函数,如:
Rectangle myrectangle(3.0, 4.6);
myrectangle.draw();

这种方法在你知道对象的具体类型时是完全有效的。然而,如果你想要编写可以处理多种形状类型的代码,使用基类指针或引用会更加灵活。例如,如果你有一个函数,它需要能够绘制任何类型的形状,你可以这样写:

void drawShape(const Shape& shape) {
    shape.draw(); // 多态性,调用正确对象的draw方法
}
int main() {
    Circle c(5.0);
    Rectangle r(3.0, 4.0);
    drawShape(c); // 传递Circle对象
    drawShape(r); // 传递Rectangle对象
    return 0;
}

这样,无论传入的是 Circle 还是 Rectangle 对象,drawShape 函数都能正确地调用相应的 draw 方法。这就是多态性的强大之处,它允许你编写更通用的代码来处理不同的对象类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九层指针

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>