成都创新互联网站制作重庆分公司

C++类型萃取(分文件管理)-创新互联

C++类型萃取(分文件管理)类型萃取
类型萃取是基于c++中的模板特化来实现的,是对于模板特化的应用。

创新互联是一家专业提供苏家屯企业网站建设,专注与成都做网站、成都网站设计、成都外贸网站建设H5页面制作、小程序制作等业务。10年已为苏家屯众多企业、政府机构等服务。创新互联专业网站制作公司优惠进行中。

以通用的拷贝函数为例

拷贝函数,c++自带的拷贝函数是俗称的浅拷贝,浅拷贝对于一些内置类型而言不会出错,但对于一些自定义类型在拷贝的时候就会出现内存访问错误(中断),想回顾浅拷贝的“同志”可以看https://blog.51cto.com/14233078/2442527
C++类型萃取(分文件管理)1.此方案虽然解决了拷贝问题,但是缺点也很明显,在每一次拷贝数据,都需要遍历一遍,时间复杂度O(1)

#include
using namespace std;
#include

template
void Copy1(T* dst, T* src, size_t size)
{
    memcpy(dst, src, sizeof(T)*size);
}

// 优点:一定不会出错
// 缺陷:O(N)
template
void Copy2(T* dst, T* src, size_t size)
{
    for (size_t i = 0; i < size; ++i)
        dst[i] = src[i];
}

bool IsPODType(const char* strType)
{
    // 此处可以将所有的内置类型枚举出来
    const char* strTypes[] = { "char", "short", "int", "long", "long long", "float", "double" };
    for (auto e : strTypes)
    {
        if (strcmp(strType, e) == 0)
            return true;
    }

    return false;
}

template
void Copy(T* dst, T* src, size_t size)
{
    // 通过typeid可以将T的实际类型按照字符串的方式返回
    if (IsPODType(typeid(T).name()))
    {
        // T的类型:内置类型
        memcpy(dst, src, sizeof(T)*size);
    }
    else
    {
        // T的类型:自定义类型---原因:自定义类型中可能会存在浅拷贝
        for (size_t i = 0; i < size; ++i)
            dst[i] = src[i];
    }
}

void TestCopy()
{
    int array1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    int array2[10];
    Copy(array2, array1, 10);

    string s1[3] = { "1111", "2222", "3333" };
    string s2[3];
    Copy(s2, s1, 3);
}

int main()
{
    TestCopy();
    return 0;
}

C语言参与编译的是.c文件,一个.c文件是一个编译单元。
头文件在预处理阶段被展开,即,预处理器看见#include预处理指令的时候,就用相应头文件的内容替换掉这个#include预处理指令(把头文件内容拷贝到.c文件中,然后删除这条#include预处理指令)。
你应该把头文件看出是导出给外部模块使用的接口,里面存放外部模块需要使用的宏定义及函数原型。
在linux下,可以用gcc -E查看预处理之后的文件。
头文件中的函数原型是提供给编译器作为函数原型检查的,对于不是本源文件中的函数,编译过程中并不会产生实际的调用代码(函数调用需要知道确切的函数地址),只是在相应的地方做个标记,表示在这里需要调用某个函数。编译完成产生的是汇编代码。
如上所述,编译产生的汇编代码并不能直接运行,因为外部函数调用的地方还没给予确切的函数地址。这个工作由链接过程完成。链接器会查找其它源文件所产生的汇编代码,进而找到正确的函数调用地址,然后用这个地址替换掉在编译时做的标记。完成这一步后,程序就可以实际运行了。
因此,.h是根本不会被编译的,它如果被包含,则会被预处理器将其内容一分不差的拷贝到.c文件中,.编译器编译的是拷贝后的这个.c文件。

2.分文件管理:
因为头文件在预处理阶段就已完成,所以不会降低代码效率,因此解决1中代码效率低的问题

头文件

#pragma once

#include
using namespace std;
#include

//来自自定义类型
struct TrueType
{};

// 对应自定义类型
struct FalseType
{};

//隐示实例化
template
struct TypeTraits
{
    typedef FalseType PODTYPE;  // plain old data
};

//显示实例化
template<>
struct TypeTraits
{
    typedef TrueType PODTYPE;
};

template<>
struct TypeTraits
{
    typedef TrueType PODTYPE;
};

template<>
struct TypeTraits
{
    typedef TrueType PODTYPE;
};
template<>
struct TypeTraits
{
    typedef TrueType PODTYPE;
};

template<>
struct TypeTraits
{
    typedef TrueType PODTYPE;
};

template<>
struct TypeTraits
{
    typedef TrueType PODTYPE;
};

template<>
struct TypeTraits
{
    typedef TrueType PODTYPE;
};

void TestCopy();

源代码

#include"Type_extraction.h"

template
void Copy(T* dst, T* src, size_t size, TrueType)
{
    // T的类型:内置类型
    memcpy(dst, src, sizeof(T)*size);
}

template
void Copy(T* dst, T* src, size_t size, FalseType)
{
    // T的类型:自定义类型---原因:自定义类型中可能会存在浅拷贝
    for (size_t i = 0; i < size; ++i)
        dst[i] = src[i];
}

template
void Copy(T* dst, T* src, size_t size)
{
    Copy(dst, src, size, TypeTraits::PODTYPE());
}

void TestCopy()
{
    int array1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    int array2[10];
    Copy(array2, array1, 10);

    string s1[3] = { "1111", "2222", "3333" };
    string s2[3];
    Copy(s2, s1, 3);
}

测试文件main.c

#include"Type_extraction.h"

int main()
{
    TestCopy();
    return 0;
}

模板的声明和定义必须放在一个文件原因
https://blog.csdn.net/chigusakawada/article/details/78752668
显示实例化,隐式实例化概念
https://blog.csdn.net/qiujianjian/article/details/84792608

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


分享文章:C++类型萃取(分文件管理)-创新互联
文章链接:http://cxhlcq.com/article/dogidc.html

其他资讯

在线咨询

微信咨询

电话咨询

028-86922220(工作日)

18980820575(7×24)

提交需求

返回顶部