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

时间:2018-02-01 12:10:07

标签: c++ polymorphism base-class

我正在学习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;

}

2 个答案:

答案 0 :(得分:1)

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

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

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

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

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

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

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

答案 1 :(得分: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;

}

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