OOP与GP是C++中协同而非互斥的抽象机制:OOP聚焦“谁来做”,通过类、继承、多态建模实体;GP聚焦“怎么做才通用”,借模板实现编译期类型无关复用。
面向对象编程(OOP)和泛型编程(GP)在C++中是两种不同维度的抽象机制,不是互斥的替代关系,而是常协同使用的思想工具。OOP关注“**谁来做**”——通过类、继承、多态建模现实或逻辑中的实体与行为;GP关注“**怎么做才通用**”——通过模板让算法和数据结构脱离具体类型,实现编译期的类型无关复用。
OOP以“分类+封装+交互”为逻辑起点:把数据和操作打包成类,用继承表达共性与差异,靠虚函数实现运行时多态。比如Shape → Circle / Rectangle,调用draw()时行为由实际对象决定。
泛型编程以“抽象掉类型”为第一目标:不关心具体是int还是std::string,只关注类型是否支持所需操作(如+、==、迭代器解引用)。比如std::sort(first, last)对任意满足随机访问和可比较的类型都有效。
OOP的抽象单位是**类/对象**,强调“状态+行为”的统一,适合描述具有明确身份、生命周期和交互协议的实体(如BankAccount、NetworkConnection)。
GP的抽象单位是**模板+概念(C++20后)**,强调“操作契约”,例如std::ranges::range不规定内部怎么存,只要求能获得begin/end迭代器;std::invocable不关心是函数指针、lambda还是重载了operator()的类,只要可调用就行。
真实项目中,二者
极少单用。典型例子:
std::vector是泛型容器(模板类),但内部封装了内存管理、异常安全等OOP式职责std::shared_ptr用模板参数化所指类型,却用引用计数对象(带构造/析构/拷贝控制)体现OOP思想Widget是基类(OOP),而Signal是泛型事件槽(GP)选范式不是非此即彼,而是看问题本质:需要表达“is-a”或“has-a”关系?优先OOP;需要写一个和类型无关的算法或容器?优先GP;既要灵活接口又要清晰语义?两者一起上。
基本上就这些。理解区别是为了更自觉地选择工具,而不是背概念。C++的强大,正在于它不强迫你只用一种方式思考问题。