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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c ++多态 - 将对基类的引用传递给函数相关的知识,希望对你有一定的参考价值。

我正在学习c ++多态性。在下面的代码中,创建一个名为shape的指针,类型为基类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;

}
答案
#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;

}

如果您还有任何问题,请随时在评论中提问!

另一答案

我猜你的问题是技术上是如何调用在运行时调度的getArea

C ++标准没有规定这一点。它规定了必须执行哪些实现,而不是如何实现。

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

多重遗传有并发症,但那些只是:并发症。

另一种方法是搜索每个调用的基类链。

这样效率会降低,但至少在其他语言中使用它,例如最初的Smalltalk,以及20世纪90年代Windows中Pascal的Borlands GUI类框架。

另一种方法是直接在每个对象中放置指向每个虚函数的指针,实质上是每个对象中的vtable。这种方法有时在C中使用。主要优点是它在概念上很简单。它也避免了一个间接。但它浪费了空间,并没有很好地概括。

以上是关于c ++多态 - 将对基类的引用传递给函数的主要内容,如果未能解决你的问题,请参考以下文章

通过基类的指针或引用调用虚函数构成多态

python类的继承!!谁能用通俗的方法,给小弟讲一下,类的继承!!

c++中的虚函数有啥作用?

深入C++对象模型&虚函数表

关于C++基类、派生类的引用和指针

为什么基类的析构函数要写成虚函数?