2016-06-08 8 views
-2

habe ich ein grundlegendes Verständnis dieses Zeigers in C++ Während des Studiums über den folgenden Code gekommen sind.‚this‘ Zeiger Verhalten in C++

#include<iostream> 
using namespace std; 

class Test 
{ 
private: 
int x; 
int y; 
public: 
//Test (int x = 0, int y = 0) { this->x = x; this->y = y; } 
Test setX(int a) { x = a; return *this; } 
Test setY(int b) { y = b; return *this; } 
void print() { cout << "x = " << x << " y = " << y << endl; } 
}; 

int main() 
{ 
Test obj1; 
obj1.setX(10).setY(20); 
obj1.print(); 
return 0; 
} 

Mein Problem ist, warum der Compiler melden deosn't einen Fehler in dem Ich gebe einen this-Zeiger in SetX- und SetY-Funktionen zurück, habe aber den Rückgabetyp nicht als Zeiger angegeben?

+4

'this' hat Typ von' Test * ',' * this' hat Typ von 'Test'. –

+3

'setX' und' setY' sollten eine Referenz ('Test &') zurückgeben, damit der Code in 'main' korrekt funktioniert. Andernfalls wird eine temporäre Kopie geändert. – interjay

+0

@ interjay..Wollte nur eine klarere Erklärung..Wenn wir bereits den Test-Typ zurückgeben, dann ist das temporäre Variable und nicht das Original – Omkar

Antwort

3

Dies kommt, weil Sie *this nicht this zurückgeben.

this ist der Zeiger auf ein Objekt vom Typ Test. Dies bedeutet, dass die this -variable grundsätzlich die Adresse enthält, an der das Objekt gespeichert ist. Um auf das Objekt zuzugreifen, auf das this zeigt, verwenden Sie die *.

Sie geben also das tatsächliche Objekt zurück, auf dem Sie this Pointer zeigt.


EDIT

Das Problem, warum Ihr Code in der Sie es durch die Tatsache veranlasst wird, tun wollen Weg nicht funktioniert, dass Sie auf dem Stapel arbeiten.

Schauen wir uns die Adressen einen Blick:

#include<iostream> 
using namespace std; 

class Test 
{ 
private: 
    int x; 
    int y; 
public: 
//Test (int x = 0, int y = 0) { this->x = x; this->y = y; } 
    Test setX(int a) { x = a; return *this; } 
    Test setY(int b) { 
     y = b; 
     cout << this << endl; // >> 0x29ff18 
     return *this; 
    } 
    void print() { cout << "x = " << x << " y = " << y << endl; } 
}; 

int main() 
{ 

    Test obj1; 
    cout << &obj1 << endl; // >> 0x29ff10 
    obj1 = obj1.setX(10).setY(20); 
    cout << &obj1 << endl; // >> 0x29ff10 
    //obj1.setY(20); 
    obj1.print(); 
    return 0; 
} 

Wie Sie an einer anderen Adresse innerhalb Sie setY Methode zum main Vergleich sehen können, auf das Objekt, wo this Punkten. Dies liegt daran, das Objekt des Stapelrahmen der setY Methode kopiert wird - so innerhalb setX und setY Sie mit einer Kopie arbeiten von obj1

Wenn Sie tun obj1.setX(10).setY(20); Sie im Grunde das Objekt obj1 und Verwendung kopieren es innerhalb setX und das Rückkehrobjekt von setX wird dann in setY verwendet. Wenn Sie die letzte Kopie speichern möchten, müssen Sie sie obj1 zuweisen.

Ihre Lösung für das Problem funktioniert, ist aber äußerst ineffizient. Der letzte Abschnitt, der beschreibt, was passiert, ist falsch. setx wird mit aufgerufen und verwendet obj1. sety wird mit aufgerufen und verwendet die Kopie von obj1. obj1 wird dann die Kopie der Kopie von obj1 zugewiesen, die von der Datei geliefert wird. Die Adresse ändert sich nicht, weil der Speicher von obj1 überschrieben, nicht ersetzt wird. Fügen Sie einen Kopierkonstruktor und einen Zuweisungsoperator hinzu und Sie können sehen, was wirklich passiert. Die empfohlene Lösung besteht darin, Verweise auf das gleiche Objekt zu verwenden und die Verkettung gemäß der unten stehenden Antwort von @ πάνταῥεῖ durchzuführen. - user4581301

+0

Ok, nach Ihrer Antwort, wenn das tatsächliche Objekt zurückgegeben wird, dann sollte es den Wert von y zu ändern.Aber die Ausgabe für obigen Code ist: x = 10 y = 0 – Omkar

+0

Siehe meine bearbeitete Antwort. – falx

+0

@falx Sie sind auf der völlig falschen Spur. Ich habe keine Ahnung, warum das so stark aufgewertet wurde. –

2

Mein Problem ist, warum die Compiler deosn't einen Fehler melden, wo ich einen dieses Zeigers in SETX und Sethos Funktionen zurückkehre, aber noch nicht den Rückgabetyp als Zeiger angegeben?

Es ist vollständig gültige Syntax, so dass der Compiler keine Fehlermeldung zurückgeben soll. Das Problem ist, dass Sie Kopien von this* mit Ihrem Rückgabetyp verwenden.

Test& setX(int a) { x = a; return *this; } 
//^
Test& setY(int b) { y = b; return *this; } 
//^

Ansonsten sind Sie eine unabhängige Kopie Ihrer Klasse Rückkehr:


Um Chain-Operationen richtig auf der ursprünglichen Instanz zurückgeben einen Verweis auf this zu betreiben.