【C++】template vs virtual function

本文对比分析了泛型编程与抽象接口在实现代码重用和接口抽象方面的应用,通过具体的锁类实例展示了两种方法的不同之处,并探讨了它们在设计时的选择依据。

泛型编程和抽象接口都能达到代码重用和接口抽象的作用,STL是泛型编程的代码,而设计模式里面遍布了各种抽象接口,对于同样的问题,两种方法都能实现。


比如,我要实现一个锁类,泛型会这样实现:


使用时,给CGuard类传递不同的LOCK就成,比如,CGuard<CMutex> guard(m_qumutex)


如果用抽象接口,我可以这样:

 

用就这样CGuard guard(m_lock),其中,m_lock时CLock* 类型,使用时根据需要new一个具体的实际lock,如前面的CMutex。

 

于是,我纠结了,那我在设计时,到底应该怎么取舍呢?能看出的区别就是,template是compile time,virtual function是runtime,compile time类型安全一点吧,性能上runtime要看编译器,可如果就这样,还是不足以作为我选择的条件啊!昨天瞄了一下一本叫《Modern C++ Design Generic Programming and Design Patterns Applied》,上面讲了点儿policy和virtual function的区别,其中有一段话是这样说的:
Note that policies are quite different from mere virtual functions. Virtual functions promise a similar effect: The implementer of a class defines higher-level functions in terms of primitive virtual functions and lets the user override the behavior of those primitives. As shown above, however, policies come with enriched type knowledge and static binding, which are essential ingredients for building designs. Aren't designs full of rules that dictate before runtime how types interact with each other and what you can and what you cannot do? Policies allow you to generate designs by combining simple choices in a typesafe manner. In addition, because the binding between a host class and its policies is done at compile time, the code is tight and efficient, comparable to its handcrafted equivalent.

也就是说,泛型编程这种compile time policy的实现是语法绑定的,它的核心是用什么样的语法去组织一个类,而不是像virtual function那样注重的是哪些确实的功能需要我们实现。

 

我想,到底在设计中使用哪种方式还是看程序员自己怎么想吧,想清楚一个类在整个设计中的位置和它的behavior是关键,另外经验也许能指导我在具体问题中应该怎么进行选择。

 

所以,纠结了两天,先到这里吧,继续我的项目,不然真写不完咯,实践出真知,我想过段时间再来看今天写的东西定会有不同的感受。

<think> 我们参考了多个站内引用,包括函数的基本概念、虚函数、匿名函数以及数学函数sqrt的使用。 根据用户需求:获取关于C++函数的介绍、使用方法及相关知识,我们将从以下几个方面进行讲解: 1. 函数的定义与声明 2. 函数的调用与参数传递 3. 函数重载 4. 函数模板 5. 虚函数(多态) 6. 匿名函数(Lambda表达式) 7. 常用库函数示例(如sqrt) 注意:我们按照系统级指令要求,行内数学公式使用$...$,独立公式使用$$...$$,并单独成段。 同时,我们将生成相关问题放在最后。 开始回答: </think> ### C++ 函数详解 #### 1. **函数基础** 函数是C++程序的基本模块化单元,包含定义、声明和调用三要素: ```cpp // 声明 int add(int a, int b); // 定义 int add(int a, int b) { return a + b; } // 调用 int result = add(3, 5); // 返回8 ``` - **参数传递**: - 值传递:创建副本(默认方式) ```cpp void swap(int a, int b) { ... } // 不影响实参 ``` - 引用传递:直接操作原变量 ```cpp void realSwap(int &a, int &b) { ... } // 修改实参 ``` #### 2. **函数重载** 允许同名函数处理不同类型/数量的参数: ```cpp double add(double a, double b) { return a + b; } // 处理浮点数 ``` #### 3. **函数模板** 泛型编程工具,编译器自动生成具体函数: ```cpp template <typename T> T max(T a, T b) { return (a > b) ? a : b; } // 调用 cout << max<int>(5, 10); // 输出10 cout << max<double>(3.14, 2.99); // 输出3.14 ``` #### 4. **虚函数与多态** 实现运行时多态的核心机制: ```cpp class Animal { public: virtual void sound() { // 虚函数声明 cout << "Animal sound"; } }; class Cat : public Animal { public: void sound() override { // 重写虚函数 cout << "Meow"; } }; // 使用 Animal *a = new Cat(); a->sound(); // 输出"Meow"(动态绑定)[^2] ``` #### 5. **匿名函数(Lambda)** C++11引入的轻量级函数对象: ```cpp auto square = [](int x) -> int { return x * x; }; cout << square(5); // 输出25 [^3] // 捕获外部变量 int factor = 3; auto multiplier = [factor](int x) { return x * factor; }; ``` #### 6. **常用库函数示例** 数学函数使用: ```cpp #include <cmath> double root = sqrt(25.0); // 平方根函数,返回5.0 [^4] // 解二次方程应用 double discriminant = b*b - 4*a*c; if (discriminant >= 0) { double root1 = (-b + sqrt(discriminant)) / (2*a); } ``` ### 核心优势 - **模块化**:分解复杂任务 - **代码复用**:避免重复逻辑 - **可维护性**:局部修改不影响全局 - **多态支持**:通过虚函数实现接口统一[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值