c ++多态性 - 将对基 class 的引用传递给函数

c++ polymorphism - passing a reference to base class to a function

我正在学习 C++ 多态性。在下面的代码中,创建了一个名为 shape 的指针,其类型为 class Shape,然后指向对象 rc

然后调用函数 printArea(r);printArea(c);。但是,在调用这些函数的地方 shape 指向 c 的地址。那么当你调用 printArea(r); 时它是如何工作的?

#include<iostream>
using namespace std;

class Shape {
public:
    virtual float getArea() const = 0;
};

class Rectangle : public Shape {
private:
    float width;
    float height;

public:
    Rectangle(float width, float height) : width(width), height(height) {}
    float getArea() const {return width * height;}

};

class Circle : public Shape {
private:
    float radius;

public:
    Circle(float radius) : radius(radius) {}
    float getArea() const {return 3.14159f * radius *radius;}
};

void printArea(const Shape& shape) {
    std::cout << "Area: " << shape.getArea() << std::endl;
}

int main() {

    Rectangle r(2,6);
    Shape* shape = &r;

    Circle c(6);
    shape = &c;

    printArea(r);
    printArea(c);
    printArea(*shape);

    return 0;

}

我猜你的问题是如何,从技术上讲,是在 运行 时间调度对 getArea 的调用。

C++标准没有规定这个。它准确规定了必须执行的实现,但没有规定如何完成。

几乎所有现存的 C++ 实现都通过在 class 的每个对象中放置一个隐藏指针和一个或多个虚函数来实现这一点。该隐藏指针指向table个函数指针,即指向对象动态类型class的虚方法的指针。这叫做vtable。通常,通过检查对象的 vtable 指针 并从 vtable 中的 getArea 项检索函数指针来调度调用,并调用该函数。

多重继承有复杂性,但仅此而已:复杂性。

另一种方法是为每个调用搜索基础 class 链。

那样效率会低一些,但它仍然被使用,至少在其他语言中,例如在原始的 Smalltalk 中,在 1990 年代 Windows 中的 Pascal 的 Borlands GUI class 框架中。

另一种方法是在每个对象中直接放置指向每个虚函数的指针,本质上是在每个对象中放置一个 vtable。这种方法有时在 C 中使用。主要优点是它在概念上很简单。它还避免了一种间接性。但是很浪费space,泛化不好

#include<iostream>
using namespace std;

class Shape {
public:
    virtual float getArea() const = 0;
};

class Rectangle : public Shape {
private:
    float width;
    float height;

public:
    Rectangle(float width, float height) : width(width), height(height) {}
    float getArea() const {return width * height;}

};

class Circle : public Shape {
private:
    float radius;

public:
    Circle(float radius) : radius(radius) {}
    float getArea() const {return 3.14159f * radius *radius;}
};

void printArea(const Shape& shape) {
    std::cout << "Area: " << shape.getArea() << std::endl;
}

int main() {

    Rectangle r(2,6);
    Shape* shape = &r;  // shape stores the address of object r which when further call 
    std::cout<< shape <<endl; //called sends its address
    Circle c(6);
    shape = &c; // same as r is being processed 
    std::cout<<shape<<endl; 
    printArea(r);   // same thing is taking place here reference is passed and then polymorphism come 
    printArea(c);   // into play 
    printArea(*shape);  // as the shape was given reference of c in the end it returns its value

    return 0;

}

如果还有什么问题欢迎在评论中提问!