C ++:使用带有重载箭头( - >)运算符的指针的模板

时间:2016-07-28 00:37:07

标签: c++ templates pointers operator-overloading

我为指针用法编写了这个模板类 (我需要智能指针,但我不能使用boost或C ++ 11):

template<class T>
class TreePointer{
public:
    TreePointer(){
        isRefOnly=false;  
        data=NULL;
    };
    TreePointer(T* data){
        this->data=data;
        this->isRefOnly=false;   
    }
    TreePointer(const TreePointer& anotherPtr){
        this->data=anotherPtr.data;
        this->isRefOnly=true;
    }
    virtual ~TreePointer(){
        if (!isRefOnly){                        
            delete data;
        }        
    }    
    T* operator->() const{
        return data;
    }
    void operator=(const TreePointer &anotherPtr){ 
        this->data=anotherPtr.data;
        this->isRefOnly=true;
    }        
private:
    T* data;
    bool isRefOnly;
};

我有很多方法,有很多方法,比如:

class WrittenBigClassWithManyMethods{
public:
    WrittenBigClassWithManyMethods(int v){
        this->v=v;
    }    
    int sum(WrittenBigClassWithManyMethods* a){
        return v+a->v;
    }
    int v;
};

我对智能指针的这种用法非常有效:

TreePointer<WrittenBigClassWithManyMethods> tp(new WrittenBigClassWithManyMethods(5));
WrittenBigClassWithManyMethods* simpleClass=new WrittenBigClassWithManyMethods(5);
cout << tp->sum(simpleClass);

但它的用法并不奏效:

TreePointer<WrittenBigClassWithManyMethods> tp2(new WrittenBigClassWithManyMethods(5));
cout << tp->sum(tp2);

我如何更改模板的指针,使用类型为 TreePointer 的参数调用类 WrittenBigClassWithManyMethods 的methrod sum ,而不进行任何更改class WrittenBigClassWithManyMethods 及其任何用法?如果这不可能,我如何最小化类 WrittenBigClassWithManyMethods 的更改及其用法?

2 个答案:

答案 0 :(得分:2)

通常你也想要重载一元运算符*(去引用),返回T&。然后你可以通过获取结果的地址来获得引用和原始指针:

tp1->method_that_takes_ref(*tp2); // With operator*()
tp1->method_that_takes_ptr(&*tp2); // Works, but syntax might be a bit surprising

另一种获取指针的方法是直接调用operator ->,但这有点尴尬。您最好提供某种“get”方法,例如unique_ptr中的方法,只返回原始指针:

tp1->method_that_takes_ptr(tp2.operator->()); // Works, but ugh
tp1->method_that_takes_ptr(tp2.get()); // Much clearer

答案 1 :(得分:1)

将转换运算符添加到T*

operator T*() {
    return data;
}

现在编译器会在想要将TreePointer<SomeClass>转换为SomeClass*时调用它。