目录

C工程实战入门笔记13-多态

C++工程实战入门笔记13-多态

https://i-operation.csdnimg.cn/images/cf31225e169b4512917b2e77694eb0a2.pngC++多态性实战解析

成员函数重写(非多态)

#include<iostream>
using namespace std;
#include<string>

class Widget
{
public:
	void Move(int x, int y) { x_ = x; y_ = y; }
	void Draw() { cout << "Widget Draw:" << x_ << ":"<< y_ << endl; }
	int x() { return x_; }
	int y() { return y_; }
private:
	int x_{ 0 };
	int y_{ 0 };
};

//画矩形,继承Draw
class Rect :public Widget
{
public:
	void Draw() { cout << "Rect Draw:" << x() << ":" << y() << endl; }
};

//画圆,继承Draw
class Circle :public Widget
{
public:
	void Draw() { cout << "Circle Draw:" << x() << ":" << y() << endl; }
};

int main()
{
	Widget w;// 创建基类对象
	w.Draw(); // 调用基类的Draw

	Rect re;// 创建派生类对象
	re.Move(100,100);// 调用继承自基类的方法
	re.Draw();// 调用派生类自己的Draw

	Circle ci;// 创建另一个派生类对象
	ci.Draw();// 调用派生类自己的Draw
	
	system("pause");

}

https://i-blog.csdnimg.cn/direct/d2238ff5b7dc443b842f511c8ee56893.png

多态

加入两个函数

void DrawWidget(Widget* w)
{
	w->Draw();
}

void DrawWidget(Widget& w)
{
	w.Draw();
}

main函数中加入

	cout << "------------------------" << endl;
	DrawWidget(re);
	DrawWidget(&ci);
	DrawWidget(w);

https://i-blog.csdnimg.cn/direct/3b1e056383d34d3b918c19abb991ebcf.png

void Draw() { cout << "Widget Draw:" << x_ << ":"<< y_ << endl; }

改成

virtual void Draw() { cout << "Widget Draw:" << x_ << ":"<< y_ << endl; }

添加override

//画矩形,继承Draw
class Rect :public Widget
{
public:
	void Draw() override { cout << "Rect Draw:" << x() << ":" << y() << endl; }
};

//画圆,继承Draw
class Circle :public Widget
{
public:
	void Draw() override { cout << "Circle Draw:" << x() << ":" << y() << endl; }
};

再次运行代码
https://i-blog.csdnimg.cn/direct/12bb64aae8074a3a85a70d4a17f2d787.png

多态性的优势

实际工程中应用举例

class Scene
{
public:
    void Add(Widget* w)
    {
        wids_.push_back(w);
    }
    void DrawAll()
    {
        for (auto w : wids_)
            w->Draw();
    }
    ~Scene()//防止内存泄露
	{
		for (auto w : wids_)
			delete w;
		wids_.clear();
	}
private:
    vector<Widget*>wids_;
};
  • Scene类包含一组Widget对象,可以统一管理它们;
  • 使用vector<Widget*>存储指向各种图形对象的指针;
  • 通过遍历集合,对所有对象执行相同操作(如绘制);
  • 可以轻松添加新的图形类型,无需修改Scene类,具有可扩展性

main函数中加入

int main()
{
    Scene sec;
    sec.Add(new Widget());
    sec.Add(new Circle());
    sec.Add(new Rect());
    sec.DrawAll();
}

这段代码展示了C++多态性的强大功能,特别是通过Scene类实现了:

多态容器管理多种类型的图形对象
统一接口处理不同类型的对象
易于扩展和维护的代码结构

Scene类的设计体现了面向对象设计的重要原则:

开闭原则(对扩展开放,对修改关闭)
依赖倒置原则(依赖抽象而非具体实现)
单一职责原则(每个类负责一个明确的功能)
这种设计模式是构建大型、可维护C++应用程序的基础。