采用基类类型参数的虚拟函数

Virtual function taking parameters of base class type

本文关键字:虚拟 函数 类型参数 基类      更新时间:2023-10-16

这里的多态性有什么问题?

class A
{
public:
    int x;
    virtual void dosomething(const A& ob) = 0;
};
class B : public A
{
public:
    int y;
    void dosomething(const A& ob) { // I assume this will work (base class accepting a derived class by reference)
        x += ob.x;
        y += ob.y; // error: const class A has no memeber named 'y'
        cout<<x<<"    "<<y;
    }
};

int main()
{
    B s, m;
    s.x = 3;
    s.y = 9;
    m.x = 3;
    m.y = 9;
    s.dosomething(m);
}

我尝试使用指针而不是引用,但仍然无法工作
我应该重写函数吗?

dosomething()接受对对象的A部分的引用。A没有名为y的成员,就像编译器错误所说的那样。只有B具有y成员。

想象一下,还有另一个类C,它也派生自A,而不是B,其中C也没有y成员。如果将C对象传递给B::dosomething(),您认为会发生什么?

class C : public A
{
public:
    int z;
    void dosomething(const A& ob) { ... }
};

B b;
C c;
b.dosomething(c);

这是行不通的。B::dosomething()可以接受C对象作为输入,但仍然没有y成员可供B::dosomething()读取。

因此,在访问y成员之前,必须在B::dosomething()内部使用类型转换来检查输入obj是否真的是从B派生的

class B : public A
{
public:
    int y;
    void dosomething(const A& ob) {
        x += ob.x;
        const B *b = dynamic_cast<const B*>(&ob);
        if (b) y += b->y;
        cout << x << "    " << y;
    }
};