2016-06-10 2 views
0

Ich habe geta() -Funktion erklärt, um einen Verweis auf eine, die ich sammeln muss in einem Zeiger int. Der Code funktioniert gut, aber warum konnte ich die kommentierte Zeile nicht verwenden. Tut es nicht dasselbe? Der Code ist wie folgt:Warum kann ich einen zurückgegebenen Verweis nicht direkt einem Zeiger zuweisen?

#include<iostream> 
using namespace std; 
class Foo 
{ 
    int a=6; 
public: 
    int& geta() 
    { 
     return a; 
    } 
}; 
int main() 
{ 
    Foo f; 
    int &z = f.geta();   //int *p = f.geta(); Why this doesn't work? 
    int *p = &z; 
    cout << *p; 
} 
+0

Da Sie einem Zeiger auf "int" keinen Verweis auf "int" zuweisen können. Ändern Sie zu 'int * p = & (f.geta());' – 101010

+3

Es "tut das gleiche", aber es ist nicht typsicher, oder zumindest darf es nicht implizit durch die Konvertierungsregeln von C++ geschehen. Wir denken an Werte, die sich konzeptionell von Zeigern zu diesen Werten unterscheiden, wenn Sie die Adresse nehmen wollen, die Sie schreiben müssen. Wenn es nicht so funktioniert, können bestimmte Operationen mit mehrstufigen Zeigern auf sehr kryptische Weise geschrieben werden. –

+0

@ 101010 ok..aber wie kommt es dann, dass wir * p = & z zuweisen? Gibt es keine Ganzzahlinterferenz? – Omkar

Antwort

4

nicht mit & und Symbol * verwirrt Sie. Die Bedeutung des Symbols & ist in einem Ausdruck und in einer Deklaration unterschiedlich.

Wenn es in einem Ausdruck verwendet wird, bezeichnet & den address-of-Operator, der die Adresse einer Variablen zurückgibt.

Wenn jedoch & in einer Deklaration verwendet wird (einschließlich formaler Funktionsparameter), ist es Teil des Typbezeichners und wird zum Deklarieren einer Referenzvariablen (Alias ​​/ alternativer Name) verwendet.

Referenz und Zeiger sind nicht das Gleiche. Sie hier überprüfen ... What are the differences between a pointer variable and a reference variable in C++?

0

Nun, Sie können assing Zeiger nicht in int: Vielmehr können Sie neue Speicher für Zeiger zuweisen und es wie unten Code assing Wert:

#include <iostream> 
#include <string> 

using namespace std; 
class Foo 
{ 
    int a; 
public: 
    Foo():a(6) {} 
    int& geta() 
    { 
     return a; 
    } 
}; 
int main() 
{ 
    Foo f; 
    int *p = new int; 
    *p = f.geta(); 
    //int *p = &z; 
    cout << *p; 
} 
0
using namespace std; 
class Foo 
{ 

public: 
    int a; 
    int& geta() 
    { 
     return a; 
    } 
}; 
int main() 
{ 
    Foo f; 
    f.a = 6; 
    int &z = f.geta(); //int *p = f.geta(); Why this doesn't work? 
    z = 10; // 'z' is nothing but 'a' 
    int *p = &z; 
    cout << *p; 
} 

können Sie oben sehen z ist nichts als a. beide verweisen auf denselben Speicher. und int *p ist ein Zeiger, der die Adresse enthält. so kann man entweder p = &z; oder *p = z;

int *p = f.geta(); bedeutet, dass Sie einen Verweis auf Zeigervariable Zuweisungsmittel Adresse a zu *p welche nicht gültig ist. Wenn p = &a oder p = &z bedeutet Adresse von a/z zu p zuweisen, die beim Deinferencing gibt Ihnen den Wert. pointer

0

Gute Antworten sind hier schon, also leihe ich mir einige ihrer guten Sätze aus und versuche, Ihnen eine einfachere Antwort zu geben.

Denken Sie daran, dass ein Zeiger eine Adresse des Computerspeichers ist, und wenn es mit einem Stern-Zeichen kommt, kann es bedeuten, zwei verschiedene Dinge tun: 1_definition, 2_dereferencing.

Die bemerkenswerte Sache hier ist, dass Sie in der gleichen Zeile initialisieren können, die Sie den Zeiger, oder auf separaten Zeilen definieren. So sind diese zwei Äquivalente:

int x=8; 
int *ptr=&x; //this is equivalent for 
//this: 
int *ptr; 
ptr=&x; 

Fast gleiche zwei Aufgaben mit Ampersand Zeichen fertig sind (defenition und Referenzierung).Sie können:

1_define Referenzen, aber hier sind eine subtile Sonderregel zu beachten, Sie nicht Referenzen in einer Linie definieren und sie in einer anderen verweisen. Mit anderen Worten, Sie müssen eine Referenz mit einer anderen Variablen initialisieren, wann immer Sie es definieren. und von diesem Moment an wird es ein Alias ​​ dafür! z.B. wenn es auf ein int referenziert wird, verhält es sich wirklich wie dieses! (genau wie in Ihrem Fall), der einzige Unterschied ist, dass es auch die Adresse dieses int haben wird, irgendwo hinter den Kulissen.

(Auch, wenn Sie einen Verweis auf ein Objekt zu machen, kann es nicht später beziehen sich auf andere Objekte geändert werden.)

2_Der andere Sache, der Ampersand Zeichen tun, ist (wie Monirul Islam Milon in einer anderen Antwort, sagte) die Extraktion der Adresse einer Variablen.

Jetzt, nachdem diese grundlegenden Dinge, sind Sie bereit, auf dieser einen Blick zu nehmen (besser, wenn Sie es zu laufen):

int main() 
{ 
    int j=25; 
    int* ptr; 
    ptr = &j; 
    int& ref1 = j, ref2 = *ptr; 
    //-------int& ref3 = ptr; // <-------- error! 
    //-------You can not assign an address to an int! 
    //-------Remember that in the valid examples above, ref1 and ref2 are really nothing but j 
    cout << "j is: " << j << endl; 
    cout << "ref1 is: "<< ref1 << '\t' << "ref2 is: " << ref2 << endl; 
    cout << "They are both aliases for j"; 

Im Pass-by-Referenzfunktionen, das gleiche passiert, Objekte selbst werden an diese Funktionen gesendet, allerdings in Aliasen (alternative Namen) als Parameter. Bitte beachten Sie auch, dass Sie bei der Funktion "Rückgabe über Referenz" keine Adresse zurückgeben, sondern das Objekt selbst - was auch immer es ist - über seinen Alias ​​(durch den Verweis darauf) zurücksenden. Also:

class_name& foo2(){ 
static class_name x=something; 
return x; 
} //OK 
//but: 
//-------int *ptr2 = foo2(); // <-------error! 

Wieder in der letzten Zeile, Sie versuchen, eine Klasse zuweisen (egint, Schwimmer, ein benutzerdefinierten ein, etc ...) auf einen Zeiger, der offensichtlich nicht gültig ist (basierend auf den grundlegendsten Regeln von C++). link, link, link, link:

Ich habe diese Links schreiben Sie diese Antwort für Sie verwendet.

Ich hoffe es hilft.

Verwandte Themen