读书笔记--模板与泛型编程

  • 了解隐式接口和编译期多态

    •   编译期多态和运行期多态

      •   运行期多态就好比是virtual函数再运行的时候才确定该virtual函数该被绑定为哪个函数,运行的时候才确定函数类型。
      •   编译期多态就好比是泛型编程和模板编程中,在编译的时候才确定哪个函数该被调用,根据函数的类型去确定。
    •   显示接口和隐式接口
      •   显示接口由函数的签名式构成

        class widget{
        public:
            widget();
            virtual ~widget();
            virtual std::size_t size() const;
            virtual void normalize();
            void swap(widget& other);
        };
        //这个其中:上述的这些函数都构成了这个public的显示接口
      • 隐式接口:由一组表达式组成;if (w.size()>10 && w!=somenastywidget)...
    •   classes和templates都支持接口和多态;对classes而言接口是显示的,一以函数签名为中心。多态是通过virtual函数发生在运行期;对template参数而言,接口是隐式的,基于有效表达式。多态则是通过template具现化和函数重载解析发生于编译期。
  • typename的意义
    •   在template声明式中,class和typename没有什么不同。

      template <class T> class widget;
      template <typename T>class widget;
    •   从属名称和谓非从属名称
      •   从属名称(dependent typename):表示这个变量名称是依赖于template参数的,有模板参数确定的。

        •   利用这个从属名称可能有时候会发生名称晦涩难懂,或者是名称过长导致名称无法解析。这个时候我们可以使用typename关键字,可以让编译器知道某个长名称是一个参数类型,这样可以消除歧义。
        •   一般我们在template中指涉了一个从属类型名称,就要在它前面添加关键字typename。
        •   特殊:typename不可以出现在base classes list内的从属类型名称之前,也不可在member initialization list中作为base class修饰符。
      •   谓非从属名称(non-dependent typename):这个变量是不依赖与template参数的,是一个正常的变量名称。
    •   typedef:作用是用一个简短的名称替换一个较长的名称

      typedef typename std::iterator_traits<itrat>::value_type value_type;
      //在这里 typename是指定从属名称,typedef是让这个长的从属名称变为短的value_type。
  • 学会处理模板化基类内的名称
    •   可以在派生类模板中内通过this->指涉base class templates内的成员名称,或者籍由一个明白写出的base class资格修饰符完成
  • 将于参数无关的代码抽离templates
    •   templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系。
    •   因非类型末班参数而造成的代码膨胀往往可以消除,做法是以函数参数或class成员变量替换template参数。
    •   因类型参数而造成的代码膨胀往往可以降低,做法是让带有相同二进制表述的具现类型共享实现码。
  • 运用成员函数模板接收所有兼容类型
    •   成员模板函数

      template <typename T>
      class smartptr{
      public:
          template<typename U>
          smartptr(const smartptr<U> &other);//成员模板函数
      };
    •   请使用成员模板函数生成可以收所有兼容类型的函数;如果你声明成员模板函数用于泛化copy构造函数和泛化assignment操作,你还是需要声明正常的copy构造函数和泛化assignment操作
时间: 2024-10-15 20:15:37

读书笔记--模板与泛型编程的相关文章

C++ Primer 学习笔记_77_模板与泛型编程 --实例化

模板与泛型编程 --实例化 引言: 模板是一个蓝图,它本身不是类或函数.编译器使用模板产生指定的类或函数的特定版本号.产生模板的特定类型实例的过程称为实例化. 模板在使用时将进行实例化,类模板在引用实际模板类型时实例化,函数模板在调用它或用它对函数指针进行初始化或赋值时实例化. 1.类的实例化 当编写Queue<int>qi时,编译器自己主动创建名为Queue<int>的类.实际上,编译器通过又一次编写Queue模板,用类型int取代模板形參的每次出现而创建Queue<int

c#2.0锐利体验《泛型编程》读书笔记

1.c#泛型及机制 ? 1 2 3 4 5 6 Class Stack<T> { } T 其实为type的缩小,不过也可为其他字符代替T ,被称为"泛型类型"  T为晚绑定的,在编译的时候还不能确定T的确切类型. 2.泛型类型 3. c#2.0锐利体验<泛型编程>读书笔记,布布扣,bubuko.com

C++ Primer 学习笔记_81_模板与泛型编程 --类模板成员[续1]

模板与泛型编程 --类模板成员[续1] 二.非类型形参的模板实参 template <int hi,int wid> class Screen { public: Screen():screen(hi * wid,'#'), cursor(hi * wid),height(hi),width(wid) {} //.. private: std::string screen; std::string::size_type cursor; std::string::size_type height

C++ Primer 学习笔记_82_模板与泛型编程 --类模板成员[续2]

模板与泛型编程 --类模板成员[续2] 六.完整的Queue类 Queue的完整定义: template <typename Type> class Queue; template <typename Type> ostream &operator<<(ostream &,const Queue<Type> &); template <typename Type> class QueueItem { friend clas

C++ Primer 学习笔记_75_模板与泛型编程 --模板定义

模板与泛型编程 --模板定义 引言: 所谓泛型程序就是以独立于不论什么特定类型的方式编写代码.使用泛型程序时,我们须要提供详细程序实例所操作的类型或值. 模板是泛型编程的基础.使用模板时能够无须了解模板的定义. 泛型编程与面向对象编程一样,都依赖于某种形式的多态性.面向对象编程中的多态性在执行时应用于存在继承关系的类.我们能够编写使用这些类的代码,忽略基类与派生类之间类型上的差异.仅仅要使用基类的引用或指针,基类类型或派生类类型的对象就能够使用同样的代码. 在泛型编程中,我们所编写的类和函数能够

C++ Primer 学习笔记_84_模板与泛型编程 --模板特化

模板与泛型编程 --模板特化 引言: 我们并不总是能够写出对全部可能被实例化的类型都最合适的模板.某些情况下,通用模板定义对于某个类型可能是全然错误的,通用模板定义或许不能编译或者做错误的事情;另外一些情况下,能够利用关于类型的一些特殊知识,编写比从模板实例化来的函数更有效率的函数. compare函数和 Queue类都是这一问题的好样例:与C风格字符串一起使用进,它们都不能正确工作. compare函数模板: template <typename Type> int compare(cons

C++ Primer 学习笔记_83_模板与泛型编程 --一个泛型句柄类

模板与泛型编程 --一个泛型句柄类 引言: [小心地雷] 这个例子体现了C++相当复杂的语言应用,理解它需要很好地理解继承和模板.在熟悉了这些特性之后再研究这个例子也许会帮助.另一方面,这个例子还能很好地测试你对这些特性的理解程度. 前面示例的Sales_item和Query两个类的使用计数的实现是相同的.这类问题非常适合于泛型编程:可以定义类模板管理指针和进行使用计数.原本不相关的Sales_item类型和 Query类型,可通过使用该模板进行公共的使用计数工作而得以简化.至于是公开还是隐藏下

C++ Primer 学习笔记_85_模板与泛型编程 --模板特化[续]

模板与泛型编程 --模板特化[续] 三.特化成员而不特化类 除了特化整个模板之外,还可以只特化push和pop成员.我们将特化push成员以复制字符数组,并且特化pop成员以释放该副本使用的内存: template<> void Queue<const char *>::push(const char *const &val) { char *new_item = new char[sizeof(val) + 1]; strncpy(new_item,val,sizeof(

C++ Primer 学习笔记_79_模板与泛型编程 --模板编译模型

模板与泛型编程 --模板编译模型 引言: 当编译器看到模板定义的时候,它不立即产生代码.只有在用到模板时,如果调用了函数模板或定义了模板的对象的时候,编译器才产生特定类型的模板实例. 一般而言,当调用函数时[不是模板],编译器只需看到函数的声明.类似的,定义类类型的对象时,类定义必须可用,但成员函数的定义不是必须存在的.因此,应该将类定义和函数声明放在头文件中,而普通函数和类成员函数的定义放在源文件中. 模板则不同:要进行实例化,编译器必须能够访问定义模板的源代码.当调用函数模板或类模板的成员函