C++ 学习(2) ---- 基本语法介绍

2022-11-10  本文已影响0人  特立独行的佩奇
C++ 基本语法(2)
C++基础语法 说明
模板 NA
运算符重载 NA
强制类型转换 static_cast,const_cast, reinterpret_cast,dynamic_cast
const mutable关键字
explicit 关键字
inline 关键字
函数模板

C++ 中的模板分为函数模板和类模板两种
C++中,很多函数要求能够处理许多不同类型的数据,比如比较大小的函数,既要能够比较整数也要求能够比较字符串,这些算法处理的数据是不相同的,但是算法本身是相同的,这种情况下就可以使用函数模板来简化工作
示例代码:

template <typename T> 
inline T const&  Max(T const& a, T const& b) {

    return a > b ? a : b;
}

T 表示一种抽象的数据类型,template <typename T> 也可以写成 template <class T>,译器会自动根据我们传入的标识符类型,来推导出相应的函数

调用形式:显示实例化或者隐式实例化(推导)

    //test function teamplate
    {
        cout << "Max uint32_t ret = " << Max(10, 20) << endl;
        //cout << "Max uint32_t ret = " << Max<uint32_t>(10, 20) << endl;

        cout << "Max float ret = " << Max(1.0f, 2.1f) << endl;
        //cout << "Max uint32_t ret = " << Max<float>(1.0f, 2.1f) << endl;

        string s1 = "hello";
        string s2 = "world";
        //cout << "Max string ret = " << Max(s1, s2) << endl;
        cout << "Max uint32_t ret = " << Max<string>(s1, s2) << endl;
    }
模板类

下面的代码定义了一个stack 的模板类,类中使用vector 存储数据

template <typename T>  //template <class T> is also ok
class Stack {
public:
    Stack(uint32_t size);
    void push(T const&);
    T pop();
    T top();
    bool empty();
private:
    vector<T> mvec;
};

template <typename T>
Stack<T>::Stack(uint32_t size) {
    mvec.reserve(size);
}

template <typename T>
void Stack<T>::push(T const& a) {
    mvec.push_back(a);
}

template <typename T>
T Stack<T>::pop() {
    auto p = mvec.back();
    mvec.pop_back();
    return p;
}

template <typename T>
T Stack<T>::top() {
    auto p = mvec.back();
    return p;
}

template <typename T>
bool Stack<T>::empty() {
    if (mvec.size() == 0) {
        return true;
    } else {
        return false;
    }
}

注意点:

隐式实例化的调用形式:

Stack<string> mystack(10);
mystack.push("pushA");
mystack.push("pushB");
mystack.push("pushC");
mystack.push("pushD");

string p = mystack.pop();
cout << "mysatck pop element: " << p << endl;
cout << "mysatck pop element: " << mystack.top() << endl;
cout << "mysatck empty: " << mystack.empty() << endl;
模板类的显式实例化

通常情况下,模板类的定义和实现是放在一起的,在.h和.cpp 文件中,当然也可以将它们像普通类一样分开放;
因为模板类、函数通常定义在头文件中,这些头文件会被很多cpp文件包含,在这些cpp文件中会多次使用这些模板;编译完后的可执行程序中会包含多份模板类的定义,然而实际上,整个程序中却只有一份模板类的定义,这个处理是在编译和链接过程中实现的,目前主流的实现模式有两种

g++实现的是Borland 模式,由于我们为每一份实例化生成代码,这样在大型程序中就有可能包含很多重复的实例化定义代码,虽然链接阶段,链接器会剔除这些重复的定义,但仍然会导致编译过程中的目标文件(或者共享库文件)过于庞大。这时候,我们就可以通过C++11的模板显式实例化的方法解决

下面定义Stack 模板类,实现是在 templateDemo.cpp 中

#include <stdint.h>
#include <iostream>
#include "vector"
#include "templateDemo.h"

template class Stack<uint32_t>;  //显式实例化
template class Stack<string>; //显式实例化


/*   template stack demo    */
template <typename T>
Stack<T>::Stack(uint32_t size) {
    mvec.reserve(size);
}

template <typename T>
void Stack<T>::push(T const& a) {
    mvec.push_back(a);
}

template <typename T>
T Stack<T>::pop() {
    auto p = mvec.back();
    mvec.pop_back();
    return p;
}

template <typename T>
T Stack<T>::top() {
    auto p = mvec.back();
    return p;
}

template <typename T>
bool Stack<T>::empty() {
    if (mvec.size() == 0) {
        return true;
    }
    else {
        return false;
    }
}

templateDemo.h 定义模版类Stack

#ifndef _TEMPLATEDEMO_
#define _TEMPLATEDEMO_

#include <string>
#include <vector>

using namespace std;

// template function Max
template <typename T>
inline T const&  Max(T const& a, T const& b) {

    return a > b ? a : b;
}


// template function templateprint
template <typename T>
void templateprint(T& a) {
    cout << "demo print value: " << a << endl;
}


// templaye class Stack
template <typename T>  //template <class T> is also ok
class Stack {
public:
    Stack(uint32_t size);
    void push(T const&);
    T pop();
    T top();
    bool empty();
private:
    vector<T> mvec;
};
#endif

在templateDemo.cpp 显式实例化 Stack 类模板,在其他文件中就可以很自由的include templateDemo.h;当然也可以将模板类Stack 定义实现放在一起,可以避免使用显示实例化;

上一篇下一篇

猜你喜欢

热点阅读