通过将派生类指针转换为基类指针可以实现很多功能,例如多态,接口抽象与实现分离,回调机制设计,工厂模式等。
多态性实现
多态是指同一操作(如方法调用)作用于不同的对象时,可以产生不同的行为,具体行为由对象自身的类型决定。
函数参数通用化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Animal { public: virtual void speak() const = 0; virtual ~Animal() = default; };
class Dog : public Animal { public: void speak() const override { cout << "Woof!" << endl; } };
class Cat : public Animal { public: void speak() const override { cout << "Meow!" << endl; } };
void makeAnimalSpeak(Animal* animal) { animal->speak(); }
Dog dog; Cat cat; makeAnimalSpeak(&dog); makeAnimalSpeak(&cat);
|
容器存储异构对象
统一容器管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| vector<Animal*> zoo; zoo.push_back(new Dog()); zoo.push_back(new Cat()); zoo.push_back(new Dog());
for (Animal* animal : zoo) { animal->speak(); }
for (Animal* animal : zoo) { delete animal; }
|
接口抽象与实现分离
设计模式应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| class Shape { public: virtual double area() const = 0; virtual void draw() const = 0; virtual ~Shape() = default; };
class Circle : public Shape { double radius; public: Circle(double r) : radius(r) {} double area() const override { return 3.14 * radius * radius; } void draw() const override { cout << "Drawing circle" << endl; } };
class Rectangle : public Shape { double width, height; public: Rectangle(double w, double h) : width(w), height(h) {} double area() const override { return width * height; } void draw() const override { cout << "Drawing rectangle" << endl; } };
class GraphicsEditor { vector<Shape*> shapes; public: void addShape(Shape* shape) { shapes.push_back(shape); } double totalArea() const { double total = 0; for (Shape* shape : shapes) { total += shape->area(); } return total; } };
Application myText; Application mySpred;
myText.createDocument("text"); mySpred.createDocument("spreadsheet");
myText.workWithDocument(); mySpred.workWithDocument();
|
回调机制与事件处理
事件系统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class EventListener { public: virtual void onEvent(const string& event) = 0; virtual ~EventListener() = default; };
class Button { EventListener* listener; public: void setListener(EventListener* l) { listener = l; } void click() { if (listener) { listener->onEvent("button_clicked"); } } };
class MyApp : public EventListener { public: void onEvent(const string& event) override { cout << "Handling event: " << event << endl; } };
MyApp app; Button button; button.setListener(&app); button.click();
|
工厂模式与对象创建
灵活的对象创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| class Document { public: virtual void open() = 0; virtual void save() = 0; virtual ~Document() = default; };
class TextDocument : public Document { public: void open() override { cout << "Opening text document" << endl; } void save() override { cout << "Saving text document" << endl; } };
class SpreadsheetDocument : public Document { public: void open() override { cout << "Opening spreadsheet" << endl; } void save() override { cout << "Saving spreadsheet" << endl; } };
class Application { Document* currentDoc; public: void createDocument(const string& type) { if (type == "text") { currentDoc = new TextDocument(); } else if (type == "spreadsheet") { currentDoc = new SpreadsheetDocument(); } } void workWithDocument() { if (currentDoc) { currentDoc->open(); currentDoc->save(); } } };
Application myText; Application mySpred;
myText.createDocument("text"); mySpred.createDocument("spreadsheet");
myText.workWithDocument(); mySpred.workWithDocument();
|
这样做的好处?
指的是将派生类指针转换为基类指针
抽象和封装
扩展性
1 2 3 4 5 6 7 8 9
| class Bird : public Animal { public: void speak() const override { std::cout << "Chirp!\n"; } };
Bird bird; makeAnimalSpeak(&bird);
|
维护性
设计灵活性
支持各种设计模式:
类型安全
设计清晰
总结:向上转换(派生类→基类)是面向对象编程的基石,它实现了多态性、代码复用和灵活的软件架构,是编写可维护、可扩展代码的关键技术。