PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ und Referencen


minos5000
2008-06-29, 14:18:10
Hi,

ich bin gerade bei meinen C++ versuchen in einem Beispiel auf etwas gestoßen, was mich als Java-Programmierer sehr irritiert.

Was hat es damit auf sich, dass ich in C++ eine Funktion mit Parametern aufrufen kann und es möglich ist, die Bezeichner anschließend wie Variablen weiterzuverwenden.

Z.B.:

class test {

void getInfo(info1, info2) {
...
}


Und irgendwo anders rufe ich die Funktion dann auf und kann mit den Parametern weiterarbeiten:

test->getInfo(info1, info2);

int value = info1;



In dem Beispiel funktioniert das auch prächtig, aber nun muss ich diesen Mechanismus selber anwenden. In einer Anwendung hat es funkioniert, aber in der anderen erhalte ich beim Aufruf von getInfo() die Fehlermeldung

undefined identifier 'info1'



Ich hab auch schon im Netz und Büchern nach Informationen zu dieser Vorgehensweise gesucht, aber die Suche war nicht erfolgreich.



minos

Coda
2008-06-29, 14:24:12
Wieso solltest du die Variable nicht weiterverwenden können wenn du sie als Funktionsparameter verwendet hast? Das geht in Java doch genauso.

Du übergibst in dem Beispiel auch nicht als Reference sondern als Value, d.h. es wird kopiert. Nach dem Funktionsaufruf hat sich an info1 also nichts geändert in dem Scope in dem du getInfo aufgerufen hast.

Zudem irritiert mich, dass du keine Datentypen angegeben hast in der Funktionsdeklaration. Das kompiliert so doch gar nicht.

pest
2008-06-29, 14:27:23
du musst die parameter natürlich irgendwo deklarieren.
ich denke du meinst die call-by-reference möglichkeit die es bei java nicht gibt.
also den zeiger auf die varaible übergeben, den inhalt innerhalb der methode verändern um dann außerhalb auf den veränderten inhalt zuzugreifen


void test(int *info)
{
*info = 5;
}

int i;
test(&i);

Coda
2008-06-29, 14:28:35
Wenn dann schon C++ bitte.

void test(int &info)
{
info = 5;
}

int i;
test(i);

Das ist eine Referenz.

pest
2008-06-29, 14:32:18
macht das selbe, also egal

del_4901
2008-06-29, 14:35:17
macht das selbe, also egal
Auf einen Pointer kann man Pointerarithmetik anwenden, mit einer Referenz geht das nicht. Der Compiler macht zwar in dem Beispiel den gleichen Code draus. Der Programmierer kann aber mit Pointern mehr Scheisse bauen (meißtens unbeabsichtigt), also nicht egal.
So eine Klammer bei der Dereferenzierung und Incrementierung ist schnell mal vergessen.

pest
2008-06-29, 14:38:08
Der Programmierer kann aber mit Pointern mehr Scheisse bauen (meißtens unbeabsichtigt), also nicht egal.
So eine Klammer bei der Dereferenzierung und Incrementierung ist schnell mal vergessen.

omg, dann sollte man vielleicht bei Basic bleiben, ich benutze sogar (void*) Pointer :biggrin:

del_4901
2008-06-29, 14:39:36
omg, dann sollte man vielleicht bei Basic bleiben, ich benutze sogar (void*) Pointer :biggrin:
Dann bleib du mal sicherheitshalber lieber bei Basic.

Gast
2008-06-29, 14:42:46
Der Compiler macht zwar in dem Beispiel den gleichen Code draus.
Naja... Nicht immer.
Beispielsweise werden Virtual Tables bei Referenzen nicht genutzt.

del_4901
2008-06-29, 14:44:42
Naja... Nicht immer.
Beispielsweise werden Virtual Tables bei Referenzen nicht genutzt.
kewl, wieder was dazu gelernt ^^ C++ halt, man lernt nie aus.

Obwohl, ich hab jetzt nochmal drüber nachgedacht, wenn dem so währe, würde das hier ja so gar nicht gehen:
http://en.wikipedia.org/wiki/Double_dispatch

Coda
2008-06-29, 14:57:59
Also in meinem Test gerade sieht es so aus als hat der Gast recht. Das war mir auch nicht bewusst.

Was ist denn da bitte der Grund dafür?

#include <iostream>

class Foo
{
public:
virtual void test()
{
std::cout << "Foo::test()" << std::endl;
}
};

class Bar : public Foo
{
public:
virtual void test()
{
std::cout << "Bar::test()" << std::endl;
}
};

int main()
{
Bar test;
Foo test2 = test;

test2.test();
}

Ausgabe: "Foo::test()".

del_4901
2008-06-29, 15:04:34
Also in meinem Test gerade sieht es so aus als hat der Gast recht. Das war mir auch nicht bewusst.

Was ist denn da bitte der Grund dafür?

#include <iostream>

class Foo
{
public:
virtual void test()
{
std::cout << "Foo::test()" << std::endl;
}
};

class Bar : public Foo
{
public:
virtual void test()
{
std::cout << "Bar::test()" << std::endl;
}
};

int main()
{
Bar test;
Foo& test2 = test;

test2.test();
}

Ausgabe: "Foo::test()".

Du hast ja auch das & vergessen. Was du da grad machst ist implizites casten.

Coda
2008-06-29, 15:10:25
Hast natürlich recht. Hab's kurz runterhackt und nicht aufgepasst.

Hatte mich eh schon gewundert warum es nicht geht.

del_4901
2008-06-29, 15:12:18
Hast natürlich recht. Hab's kurz runterhackt und nicht aufgepasst.

Hatte mich eh schon gewundert warum es nicht geht.

Schwamm drüber, passiert mir ständig,
Pest währ sowas aber garantiert nicht passiert.

eXistence
2008-06-29, 15:12:30
[Code...]

das kann auch nicht gehen, da test2 weder ein Pointer noch eine referenz ist, sondern ein eigenständiges Objekt (vom Typ "Foo", das kann vom typ "Bar" gar nix wissen).

Edit: mist, zu spät gewesen ;)

#include <iostream>

class Foo
{
public:
virtual void test()
{
std::cout << "Foo::test()" << std::endl;
}
};

class Bar : public Foo
{
public:
virtual void test()
{
std::cout << "Bar::test()" << std::endl;
}
};

int main()
{
Bar test;

{
Foo test2 = test;
test2.test();
}

{
Foo* test2 = &test;
test2->test();
}

{
Foo& test2 = test;
test2.test();
}

}

Ausgabe:
"Foo::test()".
"Bar::test()".
"Bar::test()".

Mit VS2005 getestet, ich bin mir aber nicht sicher, ob die letzte Variante wirklich standardkonform ist, ich meine nämlich auch mal gelesen zu haben, dass Polymorphismus nur mit Zeigern funktionieren soll...

Coda
2008-06-29, 15:18:56
Ich geh jetzt erstmal im Boden versinken ;)

minos5000
2008-06-29, 15:54:42
Wieso solltest du die Variable nicht weiterverwenden können wenn du sie als Funktionsparameter verwendet hast? Das geht in Java doch genauso.

Du übergibst in dem Beispiel auch nicht als Reference sondern als Value, d.h. es wird kopiert. Nach dem Funktionsaufruf hat sich an info1 also nichts geändert in dem Scope in dem du getInfo aufgerufen hast.

Zudem irritiert mich, dass du keine Datentypen angegeben hast in der Funktionsdeklaration. Das kompiliert so doch gar nicht.

Ups, die Datentypen hab ich vergessen hinzuschreiben. Ich poste mal den eigentliche Code aus der Anwendung, hoffentlich wirds so klarer.

Diese Funktion will ich aufrufen:

void CSystemManager::GetNetworkInfoL(TUint& aLocationCode, TUint& aCellId)
{
iPhoneInfoType = EHandsetNetworkInfo;
StartL();
aCellId = iCellId;
aLocationCode = iLocationAreaCode;

return;

}
Die Methode rufe ich an anderer Stelle im Programm folgendermaßen auf:

CSystemManager* sysManager = CSystemManager::NewL();

sysManager->GetNetworkInfoL(iLocationAreaCode, iCellId);
buf.AppendNumUC(iCellId);
console->Write(buf);


Das kuriose daran ist für mich, dass iLocatoinAreaCode und iCellId vor dem Aufruf nirgends in Test.cpp vorkommen und ich trotzdem damit arbeiten kann.

del_4901
2008-06-29, 15:59:20
Das kuriose daran ist für mich, dass iLocatoinAreaCode und iCellId vor dem Aufruf nirgends in Test.cpp vorkommen und ich trotzdem damit arbeiten kann.
Die kommen mit Sicherheit irgendwo vor ... vllt. geerbt oder global definiert?

minos5000
2008-06-29, 16:06:32
Nun, sie kommen vor, in der Klasse von GetNetworkInfoL sind dort allerdings als private deklariert.

Die Klasse sieht übrigens so aus: http://www.newlc.com/Retrieving-IMEI-IMSI-Network-Info.html

Mit dem Aufruf von GetIMSI darin hab ich keine Probleme, da wird ja auch etwas zurückgegeben, aber wie man an den Inhalt von GetNetworkInfoL kommt versteh ich nicht ganz.

Coda
2008-06-29, 20:04:01
C++ erlaubt keine Verwendung von undeklarierten Variablen. Es ist also sicher irgendwo versteckt. Da gibt's auch keine Ausnahmen.

minos5000
2008-06-29, 20:15:46
Ok, so langsam beginne ich das Sache mit den Pointern und Referenzen zu verstehen. Seh ich das dann richtig, die Methode GetNetworkInfo erhält zwei Referenzen (woher auch immer) und verändert deren Werte. Deshalb auch als Rückgabewert void, da die Referenzen bereits das Ergebnis enthalten und somit eine explizite Ausgabe der Werte überflüssig wäre.

Coda
2008-06-29, 20:22:45
Ja so sollte sich das verhalten.

pest
2008-06-29, 23:06:06
Pest währ sowas aber garantiert nicht passiert.

ach doch, ich drücke alle 10min Ctrl-F9...aber man mag es kaum glauben
es gab auch Phasen wo ich 800 Zeilen ohne zu kompilieren, fehlerfrei am Stück geschrieben habe :eek:, aber ich war jung, und stand wahrscheinlich unter Drogen ;(

RMC
2008-06-29, 23:44:15
es gab auch Phasen wo ich 800 Zeilen ohne zu kompilieren, fehlerfrei am Stück geschrieben habe :eek:, aber ich war jung, und stand wahrscheinlich unter Drogen ;(

800 Bottles of Beer mit Einzeilern :rolleyes:

pest
2008-06-30, 00:11:04
800 Bottles of Beer mit Einzeilern :rolleyes:

nee nen PPM (http://en.wikipedia.org/wiki/Prediction_by_Partial_Matching)-Algorithmus von Bottom-Up zu Top-Down Struktur umgewandelt...:)