就像《C++箴言:理解inline化的介入和排除》阐述的,定义在一个 class 内部的函数被隐式地声明为 inline(内联),而这也包括像 operator* 这样的 friend functions(友元函数)。你可以让 operator* 不做什么事情,只是调用一个定义在这个 class 之外的 helper function(辅助函数),从而让这样的 inline declarations(内联声明)的影响最小化。在本文的这个示例中,没有特别指出这样做,因为 operator* 已经可以实现为一个 one-line function(单行函数),但是对于更复杂的函数体,这样做也许是合适的。"have the friend call a helper"(“让友元调用辅助函数”)的方法还是值得注意一下的。
Rational 是一个 template(模板)的事实意味着那个 helper function(辅助函数)通常也是一个 template(模板),所以典型情况下在头文件中定义 Rational 的代码看起来大致如下:
template class Rational; // declare // Rational // template template // declare const Rational doMultiply(const Rational& lhs, // helper const Rational& rhs); // template template class Rational { public: ...
friend const Rational operator*(const Rational& lhs, const Rational& rhs) // Have friend { return doMultiply(lhs, rhs); } // call helper ... }; |
多数编译器基本上会强迫你把所有的 template definitions(模板定义)都放在头文件中,所以你可能同样需要在你的头文件中定义 doMultiply。(就像 Item 30 阐述的,这样的 templates(模澹┎恍枰?inline(内联)。)可能看起来就像这样:
template // define const Rational doMultiply(const Rational& lhs, // helper const Rational& rhs) // template in { // header file, return Rational(lhs.numerator() * rhs.numerator(), // if necessary lhs.denominator() * rhs.denominator()); } |
当然,作为一个 template(模板),doMultiply 不支持混合模式乘法,但是它不需要。它只被 operator* 调用,而 operator* 支持混合模式运算!本质上,函数 operator* 支持为了确保被相乘的是两个 Rational objects 而必需的各种 type conversions(类型转换),然后它将这两个 objects 传递给一个 doMultiply template(模板)的适当的实例化来做实际的乘法。配合行动,不是吗? Things to Remember 在写一个提供了 class template(类模板),而这个 class template(类模板)提供了一个函数,这个函数指涉到支持所有 parameters(参数)的 implicit type conversions(隐式类型转换)的 template(模板)的时候,把这些函数定义为 class template(类模板)内部的 friends(友元)。 (e129)
<<上一页
1
2
3
4
|