c++ traits提取数据类型

第一版

template<class T>
class A {       //作为承载容器
public:
    typedef T value_type;       //约定自定义类时都定义自身的类型
    T* m_a;
    explicit A(T* t) :m_a(t) { 
        //cout << "A para construct= " << *t << endl;
        //cout << "m_a address= " << m_a << endl;
    }
    A(const A& a) { 
        //cout << "A copy construct= " << this << endl;
        m_a = new T(*a.m_a);//有拷贝构造
    }
    ~A() { 
         if (m_a) {
             //cout << "A free heap var= " << *m_a << endl;
             //cout << "free m_a address= " << m_a << endl;
             delete m_a; m_a = nullptr; 
         }
    }      //会重复释放,why?不知道哪里进行了浅拷贝
    T& operator*() { return *m_a; }       //有拷贝构造
    friend ostream& operator<< <T>(ostream& out, const A<T>& a);    //友元,模板声明在类外,左移运算符重载格式
    A<T>& operator= (const A<T>& a);    //模板类,赋值运算符重载格式
};
template<class T>
A<T>& A<T>::operator= (const A<T>& a) {       //已经有模板声明了,不用在运算符处加<T>
    //cout << "A equal overload" << endl;
    if (m_a) { 
        //cout << "A free heap var= " << *m_a << endl;
        delete m_a; m_a = nullptr;
    }
    m_a = new T(*a.m_a);
    return *this; 
}
template<class T>
ostream& operator<< (ostream& out, const A<T>& a) { out << *a.m_a << endl; return out; }

template <class I>      //迭代器萃取,获得自定义数据结构类型
struct it_traits {
    typedef typename I::value_type value_type;      //提取I自身的类型,在自定义数据结构I中已定义类型I
};
template <class I>      //迭代器萃取,基本数据类型,只能用指针?     //重载
struct it_traits<I*> {      //当用指针声明时,能通过偏特化识别出,然后推导出指针指向的数据类型
    typedef I value_type;   //此处是指针指向的数据类型
};
template < class I>
typename it_traits<I>::value_type&       //不能直接用I::value_type,基本数据类型中无此成员
func(I& ite) {     //不是引用就浅拷贝了
    return *ite;    //会拷贝构造
}
//template<class T>     //废弃,2021年6月23日
//class A {       //自定义数据类型
//    T* m_a;
//public:
//    //typedef typename it_traits<T>::value_type value_type;       //约定自定义类时都定义自身的类型
//    typedef T value_typde;
//    explicit A(T t) :m_a(new T(t)) {}
//    A(const A& a) { m_a = new T(*a.m_a); }
//    ~A() {
//        cout << "free heap var= " << *m_a << endl;
//        //cout << "free heap var= " << *(m_a->m_a) << endl;
//        delete m_a;
//    }      //会重复释放,why?不知道哪里进行了浅拷贝
//    //typename it_traits<T>::value_type operator*() { return *m_a; }    //这里只会返回类型B,不是int B::m_a
    //T operator*() { return *m_a; }
//        A& operator=(const A& a) {
//            if (m_a) { delete m_a; m_a = nullptr; }
//            m_a = new T(*a.m_a); 
//            return *this; }
//    friend ostream& operator<< <T>(ostream& out,const A<T>& a);
//};
//template<class T>
//ostream& operator<<(ostream& out, const A<T>& a) { out << *a.m_a << endl; return out; }
class B {       //自定义数据类型
public:
    typedef int value_type;       //约定自定义类时都定义自身的类型
    explicit B(value_type* a) :m_a(a) { 
        //cout << "B para construct" << endl;
    }
    B(const B& a) { 
        //cout << "B copy construct" << endl; 
        m_a = new value_type(*a.m_a); 
    }
    ~B() {
        if (m_a) {
            //cout << "B free heap var= " << *m_a << endl;
            delete m_a; m_a = nullptr;
        }
    }      //会重复释放,why?不知道哪里进行了浅拷贝
    //value_type operator*() { return *m_a; }
    B& operator=(const B& b){ 
        cout << "B equal overload" << endl;
        if (m_a) { delete m_a; m_a = nullptr; }
        m_a = new value_type(*b.m_a); 
        return *this;
    }
    value_type* m_a;
    friend ostream& operator<<(ostream& out, const B& b);
};
ostream& operator<<(ostream& out, const B& b) { out << *b.m_a << endl; return out; }

void test01() {
    A<int>it(new int(2)); 
    cout << func(it) << endl;
    A<int> it2(it); cout << func(it2) << endl;
    A<int> it3(new int(22));
    it3 = it; 
    cout << func(it3) << endl;//传一个A实例,然后解引用?不能这么理解,按萃取器的思维,把A当作容器,提取A里面的int类型成员

    int* a = new int(3);
    cout << func(a) << endl;
    delete a;

    A<B>ita_b(new B(new int(4)));
    cout << func(ita_b) << endl;    //只会返回B,重载B的左移运算符就行了
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值