C++(12) 模板类、模板继承(严格模式和自由模式)

这篇具有很好参考价值的文章主要介绍了C++(12) 模板类、模板继承(严格模式和自由模式)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

模版类

1. 模版类
#include <iostream>

using namespace std;

/*
当前 Person 类型,声明了连个模版分别对应
    NameType 模版类型,名称可以看出,用于约束成员变量 name 的类型
    AgeType  模版类型,名称可以看出,用于约束成员变量 age 的类型

模版类型充当数据类型占位符,在整个类中,成员变量,成员函数,构造函数都可以使用
*/
template <typename NameType, typename AgeType>
class Person
{
public:
    Person() {}
    Person(NameType name, AgeType age) : name(name), age(age) {}
    Person(const Person & person) : name(person.name), age(person.age) {}
    ~Person() {}

    NameType getName() { return name; }
    void setName(NameType name) { this->name = name; }

    AgeType getAge() { return age; }
    void setAge(AgeType age) { this->age = age; }

private:
    NameType name;
    AgeType age;
};

int main(int argc, char const *argv[])
{
    /*
    Person 类型带有模版修饰,需要在使用之前明确模版对应的具体类型
    模版具备数据类型支持的多样性,同时一旦确定模版类型,严格遵守数据类型一致化原则

    Person 类型如何确定模版对应的具体数据类型
    格式:
    类名<模版对应具体数据类型> * 对象 = new 类型<模版对应具体数据类型>(...);
        Person<NameType, AgeType>
    */

    // p1 明确告知编译器 NameType ==> string AgeType ==> int
    // 在后续的代码中,通过 p1 调用 Person 类内函数按照以上规则完成
    Person<string, int> *p1 = new Person<string, int>();

    p1->setName("布丁");
    p1->setAge(3);

    cout << "Name : " << p1->getName() << ", Age : " << p1->getAge() << endl;

    Person<string, int> *p2 = new Person<string, int>("张三", 14);
    cout << "Name : " << p2->getName() << ", Age : " << p2->getAge() << endl;

    delete p1;
    delete p2;

    return 0;
}
2. 模版参数限制

双重限制文章来源地址https://www.toymoban.com/news/detail-835401.html

  • 限制外部类型
  • 限制模版类型
#include <iostream>

using namespace std;

template <typename DataType, typename MsgType>
class Data
{
public:
    Data() {}
    Data(DataType value, MsgType msg) : value(value), msg(msg) {}
    Data(const Data &data) : value(data.value), msg(data.msg) {}
    ~Data() {}

    DataType getValue() { return value; }
    void setValue(DataType value) { this->value = value; }

    MsgType getMsg() { return msg; }
    void setMsg(MsgType msg) { this->msg = msg; }

private:
    DataType value;
    MsgType msg;
};

/*
当前 test1 函数明确告知调用者,当前所需的参数为 Data
同时限制 Data 中对应的模版类型为 <int, string>
*/
void test1(Data<int, string> *data);

/*
当前 test1 函数明确告知调用者,当前所需的参数为 Data
同时限制 Data 中对应的模版类型为 <double, string>
*/
void test1(Data<double, string> *data);

int main(int argc, char const *argv[])
{
    /*
    双重限制
    */
    Data<int, string> *d1 = new Data<int, string>(10, "别困!");
    Data<double, string> *d2 = new Data<double, string>(3.14, "别困!!");
    Data<char, string> *d3 = new Data<char, string>('G', "遵守数据类型一致化原则");

    test1(d1);
    test1(d2);
    /*
    test1 函数重载操作,所需函数有两种情况
        Data<int, string> *
        Data<double, string> *

    并没有支持
        Data<char, string> * 考虑到双重限制,分别对应外部类型和模版类型
        因此 d3 无法作为函数 test1 的实际参数
        【注意】请遵守数据类型一致化原则
    */
    // test1(d3);

    delete d1;
    delete d2;
    delete d3;

    return 0;
}


void test1(Data<int, string> *data)
{
    cout << "value : " << data->getValue() << ", Msg : " << data->getMsg() << endl;
}

void test1(Data<double, string> *data)
{
    cout << "value : " << data->getValue() << ", Msg : " << data->getMsg() << endl;
}
3. 模版继承
3.1 严格模式
#include <iostream>

using namespace std;

/*
类带有模版,同时有子类继承当前类
    1. 自由模式
        子类带有和父类同名声明模版
    2. 严格模式【当前模式】
        子类在继承父类时,直接指定模版的具体类型,不得修改
*/

/*
MyCompare 类
    1. 声明了模版
    2. 声明纯虚函数
    3. MyCompare 是一个抽象类
*/
template <typename T>
class MyCompare
{
public:
    // 纯虚函数,并且使用了类声明的模版
    virtual bool compare(T t1, T t2) = 0;
};
/*
IntCompare 类
    1. 继承了 MyCompare 抽象类
    2. 继承父类的过程中,同时限制了模版对应的具体类型
    3. IntCompare 类没有声明模版

IntCompare 目标是一个【实现类】
    1. 必须实现 Compare 函数
    2. 父类 MyCompare 已经明确限制模版对应的具体类型为 int 类型
    3. IntCompare 目标实现的函数
        bool compare(int t1, int t2)
*/
class IntCompare : public MyCompare<int>
{
public:
    bool compare(int t1, int t2)
    {
        return t1 > t2;
    }
};

int main(int argc, char const *argv[])
{
    /*
    bool compare(long t1, long t2) {...}
        在明确 模版对应的类型为 int 类型,实现上面的函数
        实例化的过程中,会出现报错:
        纯虚拟 函数 "MyCompare<T>::compare [其中 T=int]" 没有强制替代项
    */
    IntCompare * ic = new IntCompare;

    cout << "ret : " << ic->compare(30, 20) << endl; // 1
    cout << "ret : " << ic->compare(10, 20) << endl; // 0

    return 0;
}
3.2 自由模式
#include <iostream>

using namespace std;

/*
类带有模版,同时有子类继承当前类
    1. 自由模式【当前模式】
        子类带有和父类同名声明模版
    2. 妻管严模式
        子类在继承父类时,直接指定模版的具体类型,不得修改
*/

/*
MyCompare 类
    1. 声明了模版
    2. 声明纯虚函数
    3. MyCompare 是一个抽象类
*/
template <typename T>
class BaseHandler
{
public:
    // 纯虚函数,并且使用了类名声明的模版
    virtual void handler(T t) = 0;
};

/*
MyHander 继承抽象类 BaseHandler,同时
    1. 声明和 BaseHandler 同名模版
    2. 当前模版类型尚未明确
    3. 必须实现 void hander(T t) 函数
*/
template <typename T>
class MyHandler : public BaseHandler<T>
{
public:
    void handler(T t)
    {
        cout << "数据情况 : " << t << endl;
    }
};

int main(int argc, char const *argv[])
{
    // 实例化 MyHandler 类对象,需要指定模版对应的具体类型
    MyHandler<string> * m1 = new MyHandler<string>;
    m1->handler("零零零零");

    MyHandler<int> * m2 = new MyHandler<int>;
    m2->handler(14);

    delete m1;
    delete m2;

    return 0;
}
4. 模版类的模版函数
#include <iostream>

using namespace std;

template <typename T>
class Test
{
public:
    // 当前函数使用的模版为当前 Test 类声明的模版
    void handler(T t) { cout << "value : " << t << endl; }

    /*
    模版类内的函数,期望可以自定义模版,使用的模版数据形式,约束与当前类不同
    */
    template <typename T2>
    void my(T2 t) { cout << "value : " << t << endl; }
};

int main(int argc, char const *argv[])
{
    Test<string> * test = new Test<string>;

    test->handler("零零零零");

    /*
    my 函数对应的模版类型,由实际参数决定,并不是实例化 Test 类型决定
    */
    test->my(3.14);

    return 0;
}

5. 返回值类型带有模版
#include <iostream>

using namespace std;

/*
K ==> Key   键
V ==> Value 值
*/
template <typename K, typename V>
class Data
{
public:
    Data() {}
    Data(K key, V value) : key(key), value(value) {}
    Data(const Data & data) : key(data.key), value(data.value) {}
    ~Data() {}

    K getKey() { return key; }
    void setKey(K key) { this->key = key; }

    V getValue() { return value; }
    void setValue(V value) { this->value = value; }

    /*
    友元函数中,重载运算符操作,使用的模版并不是 Data 声明的模版
    而是函数自定义模版,通过实际参数 Data 类型中的模版情况,
    限制当前函数的模版类型

    【满足注意 Data 类型展示数据操作】
    */
    template <typename K1, typename V1>
    friend ostream & operator<<(ostream & o, Data<K1, V1> * data);

private:
    K key;
    V value;
};

template <typename K1, typename V1>
ostream & operator<<(ostream & o, Data<K1, V1> * data)
{
    o << "Key : " << data->getKey() << ", Value : " << data->getValue();
    return o;
}

template <typename K, typename V>
Data<K, V> *getData(K key, V value);

int main(int argc, char const *argv[])
{
    string name = "MY";
    Data<string, int> * data = getData(name, 3);
    cout << data << endl;

    Data<double, int> * data1 = getData(6.18, 9999);
    cout << data1 << endl;

    delete data;
    delete data1;

    return 0;
}

/*
外部函数自定义模版,返回值是 Data 类型,同时
利用当前函数的实际参数对 Data 中模版数据进行
约束限制,模版具体数据情况根据参数具体数据类型确定!
*/
template <typename K, typename V>
Data<K, V> * getData(K key, V value)
{
    return new Data<K, V>(key, value);
}

到了这里,关于C++(12) 模板类、模板继承(严格模式和自由模式)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [Unity] 单例设计模式, 可供继承的单例组件模板类

    一个可供继承的单例组件模板类: 因为 Unity 是单线程的, 所以在这里没有必要使用双检索 例如你要创建一个全局的单例管理类, 可以这样使用: 尽量避免让 SingletonComponent 帮你创建组件, 因为它只是单纯的将组件创建, 并挂载到空对象上, 而不会进行任何其他行为. 如果你的组件

    2024年02月08日
    浏览(32)
  • JS的严格模式

    JavaScript的严格模式(Strict Mode)是一种在代码中启用的特殊模式,用于提供更严格的语法和错误检查,以改善代码质量和增强安全性。使用严格模式可以帮助大家避免一些常见的错误,并禁用一些不推荐使用的特性。 要启用严格模式,可以在代码的顶部或函数体的开头添加以

    2024年02月07日
    浏览(26)
  • JavaScript激活严格模式

    在JavaScript中,严格模式是一种特殊的模式,通过’use strict’;去激活严格模式!在 JavaScript 中,“use strict” 是一种指令,表示在代码运行时启用严格模式,从而禁止使用一些不安全或者不规范的语法,减少代码出错的可能性。 看上面的代码,意思如果你通过测试,你可以拿

    2024年02月13日
    浏览(23)
  • html开启严格模式

    !DOCTYPE html是html5标准网页声明,原先的是一串很长的字符串,现在是这个简洁形式,支持html5标准的主流浏览器都认识这个声明。在 HTML5 中,!DOCTYPE html声明唯一的作用是启用标准模式。 注意,!DOCTYPE 声明位于文档中的最前面的位置,处于 html 标签之前。DOCTYPE是document type(文

    2024年02月20日
    浏览(25)
  • 设计模式之模板模式(C++)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处        模板模式是一种行为型的软件设计模式,在父类中定义了一个模板算法,只实现模板中的公共部分,将可变部分放在子类中实现,不同的子类对同一模板有不同的

    2023年04月10日
    浏览(26)
  • C++设计模式之 模板方法模式

    【声明】本题目来源于卡码网(题目页面 (kamacoder.com)) 【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】         --什么是模板方法模式(第18种设计模式)         模板方法模式 (Template Method Pattern)是⼀种 行为型设计模式 , 它定义了⼀个算法的骨架,将 ⼀些

    2024年01月21日
    浏览(36)
  • C++设计模式22:模板方法模式

    C++ 23种设计模式系列文章目录 创建型模式 第1式 工厂方法模式 第2式 抽象工厂模式 第3式 单例模式 第4式 建造者模式 第5式 原型模式 结构型模式 第6式 适配器模式 第7式 桥接模式 第8式 组合模式

    2024年02月02日
    浏览(27)
  • 【c++】“谁想继承我的花呗-.-“继承的学习

        文章目录 前言 一、继承的语法 二、基类和派生类对象赋值转换 1.例子 2.继承中的作用域 3.派生类的默认成员 4.继承与友元 5.继承与静态成员 6.复杂的菱形继承和菱形虚拟继承 总结   继承 (inheritance)机制是面向对象程序设计 使代码可以复用 的最重要的手段,它允许程序

    2023年04月16日
    浏览(22)
  • 【C++学习】继承

    🐱作者:一只大喵咪1201 🐱专栏:《C++学习》 🔥格言: 你只管努力,剩下的交给时间! C++是面向对象的编程语言,它有很多的特性,但是最重要的就是封装,继承,多态三大特性,封装本喵就不介绍了,前面我们一直都在使用,这里本喵来详细介绍 继承 。 继承:是面向

    2023年04月09日
    浏览(25)
  • C++学习:类继承

    面相对象的主要目的之一就是提供可重用的代码。 类继承就是从已有的类派生出新的类,而派生类继承了原有类,也就是基类的特征和成员函数。 继承一笔财富比自己白手起家要简单的多,写代码也是一样。 下面是可通过继承来外城的工作: 1、可以在已有类的基础上添加

    2024年02月08日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包