码迷,mamicode.com
首页 > 编程语言 > 详细

c++踩坑大法好 typedef和模板

时间:2020-02-11 16:23:21      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:实现   change   ret   and   开始   ==   千万   应该   执行   

1,typedef字面意思,自定义一种数据类型

语法:typedef 类型名称 类型标识符;

基本用法:

1) 为基本数据类型定义新的类型名。

2) 为自定义数据类型(结构体、公用体和枚举类型)定义简洁的类型名称。

3) 为数组定义简洁的类型名称。

4) 为指针定义简洁的名称。

简单使用实例:

int main() {
    using namespace std;
    typedef int hehe;
    //相当于定义一个新的数据类型类型
    hehe a = 12;
    hehe(bb) = 34;
    //这两种实现方法是一样的效果,语法而已
    printf("%d\n,%d",a,bb);
    typedef int f();
    //相当于定义一个返回int的函数f
    f(daqing);
    //等价于声明int daqing(),相当于daqing这个变量也是一个函数名称,实现在main后面
    int test = daqing();
    printf("test%d",test);
    return 0;
}
int daqing() {
    return 99;
}

2,模板(函数模板)

c++中模板存在的意义:

如果是python,想要交换两个变量的内容:

def exchange(x,y):
    a=x;
    x=y;
    y=a;
    return (x,y)
#整数交换 
x,y=1,10
x,y=exchange(x,y)
print(x,y)
#字符串交换
x,y="a","bcd"
x,y=exchange(x,y)
print(x,y)

但是如果是c++,这样做明显是不行的,本人菜鸟,写出交换两个整数的代码如下:

void daqing(int *x,int *y);
void daqing(int *x,int *y) {
    int a = *x;
    *x = *y;
    *y = a;
}
int main() {
    using namespace std;
    int a = 1;
    int b = 2;
    daqing(&a,&b);
//此处相当于把a,b的地址传递给了daqing函数,而daqing函数拿到的是*&a,*&b,(x和y相当于&a,&b)相当于a和b的值,刚开始*x=1,*y=2,int a 作为局部变量保存了*x的值,1,然后x,y交换。
    printf("%d,%d\n",a,b);
    return 0;
}

如果想交换两个char或者double,那就得把代码copy一遍,然后把声明和实现的代码中的类型全都变了,好费劲啊,所以这时候我们就需要模板啦。

书上的实例:

#include "pch.h"
using namespace std;
template <typename AnyType>
//电脑电脑,我要建立一个模板,模板名称是AnyType,关键字template和typename是必须的
void Swap(AnyType &a, AnyType&b);

int main() {
    int a = 1;
    int b = 2;
    Swap(a,b);
    printf("%d,%d\n",a,b);
    double aa = 10;
    double bb = 20;
    Swap(aa,bb);
    printf("%f,%f\n", aa, bb);
    string aaa = "12";
    string bbb = "abc";
    Swap(aaa,bbb);
    cout << aaa << " " << bbb << endl;
    return 0;
}

template <typename AnyType>
void Swap(AnyType &a, AnyType&b) {
    AnyType temp;
    temp = a;
    a = b;
    b = temp;
}
//模板我来理解大约是这么个意思,就是告诉电脑,我要新建一个临时类型,类型名是自己定义的,比如anytype,等到需要用的时候,如果用的是int,那就用int代替anytype,如果是char,就用char代替anytype

 注意,函数模板不能缩短可执行程序,我的理解是,swap函数确实生成了int版本的函数,double版本和string版本,并非只有一个函数兼容了不同类型,所以对电脑来说计算量丝毫没有少哦。而模板的好处是,生成多个函数的定义更加可靠,简单。

3,类模板

 普通思想实现一个栈是这样的(本应该头文件和源文件分开,考虑到展示问题,干脆合起来了,请自行分开)

#include "pch.h"
using namespace std;
typedef unsigned long Item;
//定义一个类型,类型名是Item(实际上就是无符号整形),这样写的好处在于,unsigned long如果想变成int,可以直接改动一处。
class Stack
{
private:
    enum {MAX=10};
    //枚举,此处相当于定义了一个整形MAX变量,
    Item items[MAX];
    //建立一个数组,数组长度为10,数组以Item类型填充
    int top;
public:
    Stack();
    //构造函数
    const bool isEmpty();
    const bool isfull();
    bool push(const Item &item);
    bool pop(Item &item);
    //注意,以上都是引用传参,在函数内部修改参数值,不必return外部的参数也会变化
};
int main() {
    Stack zhan;
    Item a = 100;
    Item b = 200;
    Item c ;
    zhan.push(a);
    zhan.push(b);
    //添加两个元素到栈里
    zhan.pop(c);
    //拿出栈顶的元素,元素值用变量c来存储
    cout << c << endl;
    return 0;
}
Stack::Stack() {
    top = 0;
}
const bool Stack::isEmpty() {
    return top == 0;
}
const bool Stack::isfull() {
    return top == MAX;
}
bool Stack::push(const Item &item) {

    if (top < MAX) {
        items[top++] = item;
        //注意,此处的命令相当于top=top+1;items[top]=item;
        cout <<"push command,amount is:"<<top << endl;
        return true;
    }
    else
        return false;
}
bool Stack::pop(Item &item) {

    if (top>0) {
        item = items[--top];
        //注意,此处的命令相当于:item=items[top];top=top-1;千万小心别理解错了
        cout << "pop command,amount is:" <<top<< endl;
        return true;
    }
    else
        return false;
}

使用模板类实现的栈是这样的:

#include "pch.h"
using namespace std;
template <class Type>
//定义一个叫Type的类模板和stack类紧紧关联在一起,甚至分号都不用写了,囧。。。
class Stack
{
private:
    enum {MAX=10};
    //枚举,此处相当于定义了一个整形MAX变量,
    Type items[MAX];
    //建立一个数组,数组长度为10,数组以Item类型填充
    int top;
public:
    Stack();
    //构造函数
    bool isEmpty();
    bool isfull();
    bool push(const Type &item);
    bool pop(Type &item);
    //注意,以上都是引用传参,传递的参数是模板,就是在函数内部修改参数值,不必return外部的参数也会变化
};
int main() {
    Stack<int> zhan;
    //注意,使用栈实例的时候就不能再写Type这样的模板代号了,要写真正想要实例化的数据类型
    int a = 100;
    int b = 200;
    int c ;
    zhan.push(a);
    zhan.push(b);
    //添加两个元素到栈里
    zhan.pop(c);
    //拿出栈顶的元素,元素值用变量c来存储
    cout << c << endl;

    Stack<string> strzhan;
    //实例化一个string为模板类型的实例
    string aa = "abc";
    string bb = "aa0";
    string cc;
    strzhan.push(aa);
    strzhan.push(bb);
    //添加两个元素到栈里
    strzhan.pop(cc);
    //拿出栈顶的元素,元素值用变量c来存储
    cout << cc << endl;

    typedef double idouble;
    Stack<idouble> dbzhan;
    //实例化一个自己定义的类型为模板类型的实例,这样竟然也可以,厉害厉害
    idouble aaa = 12;
    idouble bbb = 234;
    idouble ccc;
    dbzhan.push(aaa);
    dbzhan.push(bbb);
    //添加两个元素到栈里
    dbzhan.pop(ccc);
    //拿出栈顶的元素,元素值用变量c来存储
    cout << ccc << endl;
    return 0;
}
template <class Type>
Stack<Type>::Stack() {
    top = 0;
}
//注意,实现的时候,每个函数都需要加上模板信息,否则报错,语法问题,记住就是了
//注意,普通函数实现的写法是这样的:Stack::Stack(){},但是使用了模板的函数实现的写法是这样的:Stack<Type>::Stack(){},尖括号用于说明,我是一个模板类
template <class Type>
bool Stack<Type>::isEmpty() {
    return top == 0;
}
template <class Type>
bool Stack<Type>::isfull() {
    return top == MAX;
}
template <class Type>
bool Stack<Type>::push(const Type &item) {
    if (top < MAX) {
        items[top++] = item;
        //注意,此处的命令相当于top=top+1;items[top]=item;
        cout <<"push command,amount is:"<<top << endl;
        return true;
    }
    else
        return false;
}
template <class Type>
bool Stack<Type>::pop(Type &item) {
    if (top>0) {
        item = items[--top];
        //注意,此处的命令相当于:item=items[top];top=top-1;千万小心别理解错了
        cout << "pop command,amount is:" <<top<< endl;
        return true;
    }
    else
        return false;
}

 

c++踩坑大法好 typedef和模板

标签:实现   change   ret   and   开始   ==   千万   应该   执行   

原文地址:https://www.cnblogs.com/0-lingdu/p/12269554.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!