c ++多态性 - 将对基 class 的引用传递给函数
c++ polymorphism - passing a reference to base class to a function
我正在学习 C++ 多态性。在下面的代码中,创建了一个名为 shape
的指针,其类型为 class Shape
,然后指向对象 r
和 c
。
然后调用函数 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;
}
如果还有什么问题欢迎在评论中提问!
我正在学习 C++ 多态性。在下面的代码中,创建了一个名为 shape
的指针,其类型为 class Shape
,然后指向对象 r
和 c
。
然后调用函数 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;
}
如果还有什么问题欢迎在评论中提问!