2009-12-02 6 views
6

Ich würde gerne einen Zeiger durch Verweis auf eine Funktion übergeben, so dass ich tatsächlich die Adresse ändern kann, die der übergebene Zeiger zeigt, und ich möchte dieses Argument einen Standard zuweisen Wert.C++ übergeben Zeiger per Referenz und vergeben Standardwert

etwas wie folgt aus:

in der Erklärung

void myFunc(SomeType* &var=NULL); 

und die Definition:

void MyClass::myFunc(SomeType* &var){ 
    if(var!=NULL) 
     (*var)=(*someOtherPointer); 

    if(someCondition) 
     var=NULL; 
} 

, so dass ein Angerufener kann entscheiden, ob er die Funktion mit einem Argument nennen oder ohne Argument. Und sucht, wenn er beschließt, ein Argument zu übergeben, und someCondition hält, wird der übergebene Zeiger danach

jedoch auf NULL Punkt - wenn ich versuche, es so zu tun, ich bekomme ein:

Fehler C2440: ‚default argument ':' int 'kann nicht zu' SomeType * & '

übermittelt werden Danke für die Hilfe!

Antwort

7

Die Fehlermeldung sagt alles: Sie übergeben eine ganze Zahl anstelle eines Verweises auf einen Zeiger zu SomeType. Zu tun, was Sie wollen, können Sie einen Zeiger-to-a-Zeiger-to-Sometype verwenden:

void myFunc(SomeType** var=NULL); 

void MyClass::myFunc(SomeType** var){ 
    if(var!=NULL && *var!=NULL) 
     (**var)=(*someOtherPointer); 

    if(var!=NULL && someCondition) 
     *var=NULL; 
} 
+0

Wenn "someCondition" nicht "var! = NULL" enthält, haben Sie eine Antwort akzeptiert, bei der ein NULL-Zeiger de-referenziert wird. Wahrscheinlich nicht was du wolltest. – imaginaryboy

+0

Beachten Sie auch, dass die Verwendung von (** var) = (* someOtherPointer) tatsächlich eine Objektkopie erstellt. Wenn Sie nur eine Zeigerkopie erstellen möchten, möchten Sie wahrscheinlich (* var) = (someOtherPointer). – Thought

14

NULL ist kein Lvalue - es kann nicht als Referenz übergeben werden. Es wäre so, als würde 4 an eine Funktion übergeben, die eine int& erwartet.

Der 'int' Teil ist, weil NULL ein Makro - definiert 0 ist.

Ihre beste Wette wäre die Verwendung eines Zeigers, um den Zeiger als Referenz zu übergeben, d. H. Einen Doppelzeiger. Wenn der Parameter NULL ist, wurde nichts übergeben. Wenn nicht, ist es die Adresse des Zeigers, der geändert werden sollte [um auf NULL zu zeigen, wenn acoondition gilt].

+0

+1 Sie haben es richtig schnell;) – AraK

+0

Insomnia verdammt sein. – aib

+1

Eine andere Option wäre die Verwendung von boost :: optional (kein Wortspiel beabsichtigt) –

2

Sie auch prüfen können boost :: optional (nicht die einfachste Code, den Sie verwenden können, aber die Option da ist): ich kann sehen,

void f(boost::optional<int&> r = boost::optional<int&>()) 
{ 
    if (r) *r = 5; 
} 
int main() 
{ 
    int x = 0; 
    f(x); std::cout << x << std::endl; // 5, it did change the value 
    f(); // compiler will default to an empty optional<int&> object 
} 
+0

+1 für das Beispiel. –

2

Ok, warum Sie die C++ Gehirn der Ausübung dieses aus der Perspektive tun würden, aber würden Sie tun wirklich, dass in der Produktion Code? Es sieht wie eine unglaublich nebelhafte Technik mit Nebenwirkungen aus, wenn man den Code ein Jahr später als Kollege betrachtet. Haben Sie daran gedacht, zwei separate Funktionen mit klaren Namen zu verwenden, von denen einer einen Zeiger zurückgibt und einer andere notwendige Arbeit erledigt?

2

Warum nicht einfach die Funktion überladen?

void myFunc() { 
    //whatever logic should happen if a null pointer is passed in 
} 

void myFunc(SomeType* &var) { 
    if(var!=NULL) { 
    (*var)=(*someOtherPointer); 
    } 

    if(someCondition) { 
     var=NULL; 
    } 
} 
Verwandte Themen