前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 模板开发

C++ 模板开发

作者头像
包子388321
发布2020-06-16 18:36:08
8600
发布2020-06-16 18:36:08
举报
文章被收录于专栏:包子的书架包子的书架

C++模板开发分为两类:

  • 模板函数开发
  • 模板类开发
模板函数语法:
代码语言:javascript
复制
template <class type> ret-type func-name(parameter list)
{
   // 函数的主体
}

template是关键字,<class type>表示指定的类型(类似java的泛型),ret-type表示返回类型 func-name(parameter list):函数名称和参数

  • 例子:
代码语言:javascript
复制
#include <iostream>
#include <string>
 
using namespace std;
 //模板函数
template <typename T>
inline T const& Max (T const& a, T const& b) 
{ 
    return a < b ? b:a; 
} 
int main ()
{
 
    int i = 39;
    int j = 20;
    cout << "Max(i, j): " << Max(i, j) << endl; 
 
    double f1 = 13.5; 
    double f2 = 20.7; 
    cout << "Max(f1, f2): " << Max(f1, f2) << endl; 
 
    string s1 = "Hello"; 
    string s2 = "World"; 
    cout << "Max(s1, s2): " << Max(s1, s2) << endl; 
 
   return 0;
}
模板类语法:
代码语言:javascript
复制
template <class type> class class-name {
...
}

template是关键字,<class type>表示指定的类型,class-name表示类名 例子:

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
 
using namespace std;
 
template <class T>
class Stack { 
  private: 
    vector<T> elems;     // 元素 
 
  public: 
    void push(T const&);  // 入栈
    void pop();               // 出栈
    T top() const;            // 返回栈顶元素
    bool empty() const{       // 如果为空则返回真。
        return elems.empty(); 
    } 
}; 
 
template <class T>
void Stack<T>::push (T const& elem) 
{ 
    // 追加传入元素的副本
    elems.push_back(elem);    
} 
 
template <class T>
void Stack<T>::pop () 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::pop(): empty stack"); 
    }
    // 删除最后一个元素
    elems.pop_back();         
} 
 
template <class T>
T Stack<T>::top () const 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::top(): empty stack"); 
    }
    // 返回最后一个元素的副本 
    return elems.back();      
} 
 
int main() 
{ 
    try { 
        Stack<int>         intStack;  // int 类型的栈 
        Stack<string> stringStack;    // string 类型的栈 
 
        // 操作 int 类型的栈 
        intStack.push(7); 
        cout << intStack.top() <<endl; 
 
        // 操作 string 类型的栈 
        stringStack.push("hello"); 
        cout << stringStack.top() << std::endl; 
        stringStack.pop(); 
        stringStack.pop(); 
    } 
    catch (exception const& ex) { 
        cerr << "Exception: " << ex.what() <<endl; 
        return -1;
    } 
}

上面的模板函数和模板类的例子,都是定义和声明在同一个文件中,但是如果按照传统的C++类开发,类的声明放H头文件,定义方法CPP源文件,这个时候编译会报错,提示成员函数未定义。这个问题在个人开发中一直不解,最后在网上搜索找到了合理的解释 :

在分离式编译的环境下,编译器编译某一个.cpp文件时并不知道另一个.cpp文件的存在,也不会去查找[当遇到未决符号时它会寄希望于连接器]。这种模式在没有模板的情况下运行良好,但遇到模板时就傻眼了,因为模板仅在需要的时候才会具现化出来,所以,当编译器只看到模板的声明时,它不能具现化该模板,只能创建一个具有外部连接的符号并期待连接器能够将符号的地址决议出来。然而当实现该模板的.cpp文件中没有用到模板的具现体时,编译器懒得去具现,所以,整个工程的.obj中就找不到一行模板具现体的二进制代码,于是连接器也黔
总之,在模板开发过程中,声明和定义必须放在一个文件中。当然,这个问题,也是有解决方案的,可以参考C++ 模板类的声明与实现分离问题

参考文献http://blog.csdn.net/u012750314/article/details/52770847 这是模板分离开发的实现可以借鉴: https://www.jianshu.com/p/3a7a41d46645

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C++模板开发分为两类:
    • 模板函数语法:
      • 模板类语法:
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档