一个关于模板与派生的问题

2014-08-02 13:32:50   最后更新: 2014-08-02 13:32:50   访问数量:1482




C++ programming language 第309页的例子:

template <class C> class Basic_ops //基本操作类 { public: bool operator== (const C&) const; bool operator!= (const C&) const; // ... const C& derived () const //获得操作访问权 { return static_cast <const C&> (*this); } }; template <class T> class Math_container : public Basic_ops < Math_container<T> > //具体实现的容器类 { public: size_t size() const; T& operator[] (size_t); const T& operator[] (size_t) const; // ... };

 

这样,使得有关容器的基本操作定义可以与容器本身的定义分开,而且只需定义一次

 

然而,像==、!=这样的操作必须基于容器和其元素两者来描述,所以需要将该元素类型传递给容器模板,然后将作为结果的容器类型传递给Basic_ops

例如:

template <classC> bool Basic_ops<C> :: operator== (const C &a) const { if (derived().size() != a.size()) return false; for (int i=0; i<derived().size(); ++i) if (derived()[i] != a[i]) return false; return true; };

 

我的问题是,Basic_ops<C>类中的derived ()函数存在的必要性,对于第三个例子即比较操作符的实现,*this不就是Math_container<T>类型的吗,为什么要先调用derived函数强制转换成const C&类型呢?(很明显,这里的C类型就是Math_container<T>类型啊)

 

哦,我自己想明白了,*this是Basic_ops<C>类型,而operator[]是其派生类Math_container<T>类型的操作,C++支持向上转型,但是向下转型必须要使用强制,问题原来如此简单,只是初次接触感觉比较绕,因为C++中没有java里的super,所以不得已而使用这样的方法实现,是这样吧?

还有就这个例子思考的另一个问题是,为什么operator==不设计成虚函数让子类覆盖呢?嗯,这个问题其实是因为所有的实现都共用一套operator==,没有必要去覆盖修改,这里这样设计与模板、派生没关系,因为作为容器类,比较的就是每一个元素,没有各自的比较需求,所以没有必要设计成虚函数

这个例子太巧秒了,值得今后多加品味

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,只有全部原创,只有干货没有鸡汤

 






读书笔记      技术帖      c++      cpp      技术分享      遗留问题      模板      派生      template            class      c++ programming language      已解决     


京ICP备2021035038号