我目前正在使用 C 在 OpenGL 中撰寫一個小游戲。來自非 C 背景,我有一個關于重寫方法以及如何使用超型別別的指標呼叫它們的簡單問題。
情況就是這樣:我有一個Polygon包含 method的類void draw()。這個類有兩個名為Rectangleand的子類Circle,它們都覆寫了繪圖方法,因為我使用不同的 OpenGL 呼叫,具體取決于所繪制多邊形的型別。
現在考慮一下:我希望將所有多邊形(包括矩形和圓形)存盤在std::vector<Polygon*>. 這很好。但是,遍歷向量并draw自動呼叫該方法的超類版本。
如何創建超類指標型別的向量,在其中存盤指向子類物件的指標,并根據正在使用的物件的實際型別呼叫覆寫函式?
uj5u.com熱心網友回復:
您正在描述多型性(或在您當前的實作中缺少多型性)。
要使您的draw函式具有多型性,您必須宣告它virtual。請參閱下面的示例:
class Polygon {
public:
virtual ~Polygon() {}
virtual void draw() = 0;
};
class Rectangle : public Polygon
{
public:
void draw() override { std::cout << "Rectangle::draw()\n"; }
};
class Circle : public Polygon
{
public:
void draw() override { std::cout << "Circle::draw()\n"; }
};
注意上面的三個額外的東西:
- 我還將解構式宣告為虛擬的。這允許通過其基類指標正確銷毀物件。
- 我將基本
draw方法宣告為純虛擬(= 0部分)。這意味著Polygon該類是抽象的,并且本身不能被實體化。您可能不希望這樣,但對我來說,無論如何,基類上的 draw 方法似乎沒有用。如果需要,定義一個。由你決定。 - 該
override說明符是可選的,但建議使用(C 11 引入的語言特性)。它指示編譯器您有意覆寫虛擬方法,因此如果不存在要覆寫的此類方法,則會生成編譯器錯誤。
uj5u.com熱心網友回復:
您需要在基類中將函式定義為虛擬函式,并在子類中覆寫它。例如
#include <vector>
#include <iostream>
struct A{
virtual void p(){std::cout<<"A ";}
A(){}
virtual ~A() {};
};
struct B: public A{
void p()override{std::cout<<"B ";}
B(): A(){}
};
struct C: public A{
void p()override{std::cout<<"C ";}
C() : A(){}
};
int main()
{
A* a=new A();
B* b=new B();
C* c=new C();
std::vector<A*> v={a,b,c};
for(auto i : v)
i->p();
std::cout<<"\n";
delete a;
delete b;
delete c;
return 0;
}
列印“AB C”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/459961.html
上一篇:使用不同的片段呼叫add()兩次
