2016-07-28 3 views
0

Ich schrieb diese Template-Klasse für Zeiger Verwendung (I intelligente Zeiger müssen, aber ich kann nicht boost oder C++ 11):C++: Verwendung von Template für Zeiger mit Pfeil Überlastung (->) Operator

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; 
}; 

Und ich habe große Klasse mit vielen Methoden, wie folgt aus:

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

diese Nutzung meiner Smart Pointer perfekt funktionieren:

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

Aber es Nutzung funktioniert nicht:

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

Wie ich meine Vorlage für Zeiger ändern kann, um den Aufruf methrod Summe der Klasse WrittenBigClassWithManyMethods mit Parametern vom Typ TreePointer, ohne Änderungen für die Klasse WrittenBigClassWithManyMethods und seine irgendwelche Verwendungen? Wenn das nicht möglich ist, wie minimiere ich die Änderungen für Klasse WrittenBigClassWithManyMethods und deren Verwendung?

+0

'TreePointer p = makeThingy();' wird sich wahrscheinlich nicht so verhalten, wie Sie es wollen. Dies ist kein intelligenter Zeiger, sondern eine Mischung aus unique_ptr und unformatierten Zeigern, abhängig vom booleschen Zustand. Verwenden Sie stattdessen nur unique_ptr und T &. –

+0

Oder verwenden Sie einfach 'std :: auto_ptr', was nicht C++ 11 ist. –

Antwort

2

Normalerweise sollten Sie auch den unären Operator * (de-referenz) überladen und eine T& zurückgeben. Dann können Sie sowohl eine Referenz haben und den ursprünglichen Zeiger durch die Adresse des Ergebnisses unter:

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

Ein anderer Weg, um den Zeiger zu bekommen innen wäre operator -> direkt zu nennen, aber das wäre ein wenig umständlich sein. Sie sind wahrscheinlich besser dran, eine Art von „get“ Verfahren, wie das in unique_ptr Bereitstellung, dass einfach die Rohzeiger zurückgibt:

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

einen Umwandlungsoperator zu T* hinzufügen:

operator T*() { 
    return data; 
} 

Nun ist die Compiler wird es aufrufen, wann immer es eine in eine SomeClass* konvertieren will.

+0

Das Problem mit dieser Lösung besteht darin, dass Sie dank impliziter Konvertierungen die Zeigerarithmetik direkt auf Ihr Smart-Pointer-Objekt anwenden können, was in diesem Kontext normalerweise keinen Sinn ergibt. Aus diesem Grund bietet unique_ptr keinen solchen Operator und stattdessen eine get-Member-Funktion. –

Verwandte Themen