C++之类型萃取

在初识类型萃取之前,我们可以先写一个通用的Copy函数,当然选择使用模板

void Copy(T*dst, T*src, size_t size)//通用拷贝函数
{
    memcpy(dst, src, sizeof(T)*size);
}
int main()
{
    String s1[10]={"dddd", "sss", "ccc"};
    String s2[10] = { "111", "222", "333" };
    Copy(s2, s1, 10);
    system("pause");
    return 0;
}

通过监视窗口我们可以看到确实String s2[10]这个数组将s1的内容拷贝了过来
这里写图片描述
但是程序会崩溃,在这种情况下我们首先考虑是否存在内存泄露或者多次析构的问题
首先在进行拷贝的是Sring类的对象数组,而memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
此时s1,s2指向的是同一块内存,并且s2原有的内存丢失了,析构的时候先将s2析构掉,再将s1析构掉,此时同一块内存会被析构多次,则程序一定会崩溃。
此时我们不能选择用memcpy进行拷贝,选择使用for循环

void Copy(T*dst, T*src, size_t size)//通用拷贝函数
{
    /*memcpy(dst, src, sizeof(T)*size);*/
    for (int index = 0; index < size; index++)
    {
        dst[index] = src[index];
    }
}

因为采用for循环是将对象数组的内容一个一个拷贝过来,而不是源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
比较mempy:由于是库函数,效率高,但涉及到内存问题极容易出错
for循环:不容易出错,但效率低。
如果我们拷贝的是int或者其它内置类型的数据使用memcpy不会涉及到内存问题,且效率高
如果我们涉及到自定义类型需要考虑内存问题最好使用for循环。
要注意上述程序中的’=‘是经过重载的
为了提高这个程序的质量,我们可以通过以下方法来实现
1、多传一个参数判断是深拷贝还是浅拷贝

void Copy(T* src, T* dst, size_t size,bool isPod=true)//通用拷贝函数
{
    if (isPod)
    {
        for (size_t index = 0; index < size; ++index)
        {
            dst[index] = src[index];
        }
    }
    else
    memcpy(dst, src, sizeof(T)*size);
}

2、通过判断T的类型判断是深拷贝还是浅拷贝

struct _TrueType
{
    static bool Get()
    {
        return true;
    }
};
struct _FalseType
{
    static bool Get()
    {
        return false;
    }
};
template<class T>
struct TypeTraits
{
    typedef _FalseType  _IsPod;
};
template<>//类模板的特化
struct TypeTraits<int>
{
    typedef _TrueType  _IsPod;
};
template<>
struct TypeTraits<char>
{
    typedef _TrueType  _IsPod;
};
template<class T>
void Copy(T* src, T* dst, size_t size)//通用拷贝函数
{
    if (TypeTraits<T>::_IsPod().Get())
    {
        memcpy(dst, src, sizeof(T)*size);
    }
    else 
    {
        for (size_t index = 0; index < size; ++index)
        {
            dst[index] = src[index];
        }
    }
}

总结:在涉及内存方面一定要注意深浅拷贝的问题,采用类型萃取能够提高程序的质量。类型萃取我们是通过对函数模板的特化来实现的,尤其在涉及String类的时候一定要将‘=’运算符进行重载,我之前忘记将‘=’重载,在for循环里依然出了内存泄漏和多次析构的问题,写代码时还是得细心 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值