美文网首页
C++ 学习(2) ---- 基本语法介绍

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

作者: 特立独行的佩奇 | 来源:发表于2022-11-10 10:59 被阅读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;
    }
}

注意点:

  • 定义模板类中的成员函数时,需要加上模板定义的开头 template <typename T>
  • 模板类中的成员函数,用Stack<T>指定类名

隐式实例化的调用形式:

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文件中会多次使用这些模板;编译完后的可执行程序中会包含多份模板类的定义,然而实际上,整个程序中却只有一份模板类的定义,这个处理是在编译和链接过程中实现的,目前主流的实现模式有两种

  • Borland模式(先实例化模板类,再剔除)
    Borland模式通过在编译器中加入与公共块等效的代码来解决模板实例化问题。在编译时,每个文件独立编译,遇到模板或者模板的实例化都不加选择地直接编译;在链接的时候将所有目标文件中的模板定义和实例化都收集起来,根据需要只保留一个;这种方法实现简单,但因为模板代码被重复编译,增加了编译时间,在这种模式下,我们编写代码应该尽量让模板的所有定义都放入头文件中,以确保模板能够被顺利地实例化,要支持此模式,编译器厂商必须更换支持此模式的链接器

  • Cfront模式(存储在模板存储库)
    AT&T编译器支持此模式,每个文件编译时,如果遇到模板定义和实例化都不直接编译,而是将其存储在模板存储库中(template repository);模板存储库是一个自动维护的存储模板实例的地方,在链接时,链接器再根据实际需要编译出模板的实例化代码,这种方法效率高,但实现复杂。在这种模式下,我们应该尽量将非内联成员模板的定义分离到一个单独的文件中,进行单独编译。

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 定义实现放在一起,可以避免使用显示实例化;

相关文章

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

    C++ 基本语法(2) C++基础语法说明模板NA运算符重载NA强制类型转换static_cast,const_c...

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

    C++ 基本语法 C++基础语法说明基本形式NA命名空间NA构造函数和析构函数NA实例化方法NA指针和引用NA静态...

  • swift学习(基本语法介绍)

    无意间看到自己以前学习swift的笔记,从近两年苹果的发布会,可以看出苹果推动swift的决心,OC更换为swif...

  • C++基本语法

    以leetcode刷题为驱动,学习C++基本语法。 1. 代码文件基本结构 hello world程序 假如上述代...

  • 基本语法

    语法说明 MarkDown基本介绍及使用 MarkDown语法介绍

  • C++简明教程

    本教程旨在提取最精炼、实用的C++知识点,供读者快速学习及本人查阅复习所用,后期会持续更新。 基本语法 C++ 语...

  • Oracle的nvl函数和nvl2函数

    一、基本语法 介绍一下oracle的nvl函数和nvl2函数。 nvl函数nvl函数基本语法为nvl(E1,E2)...

  • PY08-07:Cython入门

      这个主题简单介绍下Cython这种混合Python与C++语法的语言的基本工作模式。这种混合语言都有翻译器的,...

  • java的基础语法一 输出输入和变量以及随机数

    java的语法对比c和c++来学习 很容易掌握 介绍如下:注释 :单行//多行//文档注释/ */ 可以跨多...

  • C++基本语法

    C++程序可以理解为对象的集合,其基本语法和C相似,首先需要相应的环境,才能开始进行程序的编译并运行,结尾也必须使...

网友评论

      本文标题:C++ 学习(2) ---- 基本语法介绍

      本文链接:https://www.haomeiwen.com/subject/igiotdtx.html