 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Laines Guest
|
Posted: Mon May 14, 2007 5:08 am Post subject: Grundlagenfrage (Funktionen) |
|
|
Hi,
Was macht es für einen Sinn einer Funktion eine Referenz zu übergeben
(was ja den Sinn hat das sie verändert werden kann) und sie dann aber
const dranzuhängen, was ja das editieren verbietet?!?
Beispiel:
foo(const int x){}
mfg
Chris |
|
| Back to top |
|
 |
Heiko Bauke Guest
|
Posted: Mon May 14, 2007 3:05 pm Post subject: Re: Grundlagenfrage (Funktionen) |
|
|
Hi,
On Mon, 14 May 2007 02:08:37 +0200
Laines <schlafenistluxus (AT) gmx (DOT) net> wrote:
| Quote: | Was macht es für einen Sinn einer Funktion eine Referenz zu übergeben
(was ja den Sinn hat das sie verändert werden kann) und sie dann aber
const dranzuhängen, was ja das editieren verbietet?!?
Beispiel:
|
foo(const int &x){}
ja, zumindest bei komplexeren Datentypen als int. Beim Funktionsaufruf
wird sonst eine Kopie vom übergebenen Argument angefertigt. Dies kann
eine sehr komplexe Operation sein. Darum übergibt man manchmal
konstante Referenzen.
Heiko
--
-- Form follows function-that has been misunderstood. Form and function
-- should be one, joined in a spiritual union. (Frank Lloyd Wright)
-- Cluster Computing @ http://www.clustercomputing.de
-- Heiko Bauke @ http://www.physics.ox.ac.uk/users/bauke |
|
| Back to top |
|
 |
Martin Kaul Guest
|
Posted: Mon May 14, 2007 3:22 pm Post subject: Re: Grundlagenfrage (Funktionen) |
|
|
Laines wrote:
| Quote: | Hi,
Was macht es für einen Sinn einer Funktion eine Referenz zu übergeben
(was ja den Sinn hat das sie verändert werden kann) und sie dann aber
const dranzuhängen, was ja das editieren verbietet?!?
Beispiel:
foo(const int x){}
ich sehe hier keine Referenz  |
Beispiel:
class A
{
char buffer[ 1024*1024 ]; // 1MByte Daten
public:
A();
};
void functionNonRef( A obja )
{
}
void functionRef( const A &obja )
{
}
int main()
{
A obja;
functionNonRef( obja ); // kopieren von ~1MByte Daten
functionRef( obja ); // kopieren von ~4Byte Daten
return 0;
}
Beide Funktionen können dasselbe - obja nicht zu verändern. Nur beim
Aufruf von functionNonRef() wird das gesamte A Objekt kopiert und beim
Aufruf von functionRef() nur die Referenz.
tschaule
Martin |
|
| Back to top |
|
 |
Henrik Gebauer Guest
|
Posted: Mon May 14, 2007 3:28 pm Post subject: Re: Grundlagenfrage (Funktionen) |
|
|
Laines schrieb:
| Quote: | Was macht es für einen Sinn einer Funktion eine Referenz zu übergeben
(was ja den Sinn hat das sie verändert werden kann) und sie dann aber
const dranzuhängen, was ja das editieren verbietet?!?
|
Hi,
eine Variable, die als Referenz übergeben wird, wird im Speicher nicht
kopiert. Es wird dadurch ein bisschen Zeit und ein bisschen
Arbeitsspeicher gespart. Das const weißt den Compiler an, darauf zu
achten, dass die Variable nicht geändert wird.
Henrik |
|
| Back to top |
|
 |
Daniel Albuschat Guest
|
Posted: Mon May 14, 2007 3:51 pm Post subject: Re: Grundlagenfrage (Funktionen) |
|
|
Laines wrote:
^^^^^^
Ein Realname wär nett.
| Quote: | Was macht es für einen Sinn einer Funktion eine Referenz zu übergeben
(was ja den Sinn hat das sie verändert werden kann) und sie dann aber
const dranzuhängen, was ja das editieren verbietet?!?
|
Hallo,
was macht es für einen Sinn, ein Objekt, das einer Funktion nur
Informationen liefert, vor dem Aufruf der Funktion zu kopieren?
Eine konstante Referenz ist einfach bei großen Datentypen effizienter,
weil keine Kopie angelegt werden muss. Bei Datentypen ähnlich der
Größe der CPU-Register ist das Dereferenzieren der Referenz
aber wahrscheinlich langsamer als das Kopieren der kleinen Datenmenge.
| Quote: | Beispiel:
foo(const int x){}
|
Das Beispiel hat nichts mit der Frage zu tun, weil dort keine Referenz
übergeben wird. Hier findet call-by-value statt, d.h. es wird eine
Kopie angelegt. Das const könnte deshalb verwendet werden, um sicher
zu gehen, dass die funktionslokale Kopie der übergebenen Variable
am Ende der Funktion noch denselben Inhalt hat, wie am Anfang. Dadurch
ist sicher gestellt, dass der Wert nicht versehentlich innerhalb der
Funktion geändert wird.
MfG,
Daniel |
|
| Back to top |
|
 |
Gernot Bauer Guest
|
Posted: Mon May 14, 2007 4:00 pm Post subject: Re: Grundlagenfrage (Funktionen) |
|
|
Laines schrieb:
Hallo!
| Quote: | Was macht es für einen Sinn einer Funktion eine Referenz zu übergeben
(was ja den Sinn hat das sie verändert werden kann) und sie dann aber
const dranzuhängen, was ja das editieren verbietet?!?
Beispiel:
foo(const int x){}
|
Du meinst wohl sowas wie:
void foo(const int &x) {}
Das bringt im Falle eines ints wahrscheinlich nicht viel bzw. kostet
vielleicht sogar etwas Zeit.
Sinnvoll kann es aber bei komplexen Objekten sein, z.Bsp.:
void bar(const std::string &str) {}
Wenn es nicht per Referenz übergeben wird, dann wird beim Aufruf der
Funktion der copy constructor aufgerufen und das gesamte Objekt wird
kopiert[1], also auch die Daten, die darin stecken (d.h. du hast ein
new, und dann muss der Inhalt noch in den neuen Speicherbereich
übertragen werden). Beim Verlassen der Funktion wird diese temporäre
Kopie wieder zerstört (delete, ...).
Wenn du deinen Parameter als Referenz übergibst, wird kein temporäres
Objekt erzeugt und du ersparst dir den u.U. teuren copy constructor. Und
um sicherzustellen, dass der Parameter nicht verändert wird, nimmst du
das const.
lg,
Gernot
[1]: Wenn man copy-on-write-Implementierungen mal außer acht lässt |
|
| Back to top |
|
 |
Stefan Ram Guest
|
Posted: Mon May 14, 2007 4:27 pm Post subject: Re: Grundlagenfrage (Funktionen) |
|
|
Laines <schlafenistluxus (AT) gmx (DOT) net> writes:
| Quote: | Referenz zu übergeben (was ja den Sinn hat das sie verändert
werden kann) und sie dann aber const
|
Siehe die folgende Quelle.
http://www.purl.org/stefan_ram/pub/c++_referenzdefinition_de
Dort insbesondere den Abschnitt »Referenzparameter«, zu dessen
Verständnis aber das in der Lektion Vorangehende hilfreich ist. |
|
| Back to top |
|
 |
Marcel Müller Guest
|
Posted: Mon May 14, 2007 6:08 pm Post subject: Re: Grundlagenfrage (Funktionen) |
|
|
Laines schrieb:
| Quote: | Was macht es für einen Sinn einer Funktion eine Referenz zu übergeben
(was ja den Sinn hat das sie verändert werden kann) und sie dann aber
const dranzuhängen, was ja das editieren verbietet?!?
|
Performance.
Bei komplexen Objekten kann der Copy-Konstruktor sehr Zeit- bzw.
Speicheraufwendig oder sogar verboten sein (non-copyable).
foo(const T& param) ist dabei aus Sicht der Funktion in vielen
semantischen Belangen identisch zu foo(T param). Einzig, es gibt keine
lokale Kopie von param, die die Funktion auch als veränderliche, lokale
Variable nutzen könnte.
foo(const T& param) und foo(const T param) unterscheidet sich
/normalerweise/ semantisch gar nicht. Ausnahme: z.B. std::auto_ptr.
Technisch ist es ein riesen Unterschied, da im zweiten Fall T
vollständig kopiert wird.
Marcel |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Mon May 14, 2007 9:26 pm Post subject: Re: Grundlagenfrage (Funktionen) |
|
|
Laines <schlafenistluxus (AT) gmx (DOT) net> writes:
| Quote: | Was macht es für einen Sinn einer Funktion eine Referenz zu
übergeben (was ja den Sinn hat das sie verändert werden kann) und
sie dann aber const dranzuhängen, was ja das editieren verbietet?!?
|
Die Veränderung ist nur ein Zweck, nicht *der* Zweck.
Objekte können Identität haben, und die Objektadresse ist eine
mögliche Implementation von Objektidentität. Wenn das der Fall ist,
spielt es für das Verhalten des Programms eine entscheidende Rolle, ob
ich einer Funktion ein bestimmtes Objekt (per Referenz) übergebe oder
eine Kopie des Objekts.
Das kann so weit gehen, dass man Klassen schreibt, deren Instanzen
sich gar nicht kopieren lassen. Dann wird der Compiler einen daran
hindern, ein Objekt per Kopie zu übergeben. |
|
| Back to top |
|
 |
Christoph L. Guest
|
Posted: Mon May 14, 2007 10:07 pm Post subject: Re: Grundlagenfrage (Funktionen) |
|
|
Daniel Albuschat schrieb:
| Quote: | Laines wrote:
^^^^^^
Ein Realname wär nett.
Was macht es für einen Sinn einer Funktion eine Referenz zu übergeben
(was ja den Sinn hat das sie verändert werden kann) und sie dann aber
const dranzuhängen, was ja das editieren verbietet?!?
Hallo,
was macht es für einen Sinn, ein Objekt, das einer Funktion nur
Informationen liefert, vor dem Aufruf der Funktion zu kopieren?
Eine konstante Referenz ist einfach bei großen Datentypen effizienter,
weil keine Kopie angelegt werden muss. Bei Datentypen ähnlich der
Größe der CPU-Register ist das Dereferenzieren der Referenz
aber wahrscheinlich langsamer als das Kopieren der kleinen Datenmenge.
Beispiel:
foo(const int x){}
Das Beispiel hat nichts mit der Frage zu tun, weil dort keine Referenz
übergeben wird. Hier findet call-by-value statt, d.h. es wird eine
Kopie angelegt. Das const könnte deshalb verwendet werden, um sicher
zu gehen, dass die funktionslokale Kopie der übergebenen Variable
am Ende der Funktion noch denselben Inhalt hat, wie am Anfang. Dadurch
ist sicher gestellt, dass der Wert nicht versehentlich innerhalb der
Funktion geändert wird.
MfG,
Daniel
|
Es sollte natürlich so aussehen:
foo(const int &x){}
hab mich nur verschrieben... |
|
| Back to top |
|
 |
Christoph L. Guest
|
Posted: Mon May 14, 2007 10:18 pm Post subject: Grundlagenfrage (Funktionen) Danke!!! |
|
|
Danke für eure zahlreichen und gut beschriebenen Erklärungen.
Habs verstanden :-)
euer
Chris |
|
| Back to top |
|
 |
Thomas Thiele Guest
|
Posted: Tue May 15, 2007 3:11 pm Post subject: Re: Grundlagenfrage (Funktionen) Danke!!! |
|
|
On 14 Mai, 19:18, "Christoph L." <schlafenistlu...@gmx.net> wrote:
| Quote: | Danke für eure zahlreichen und gut beschriebenen Erklärungen.
Habs verstanden
|
Vielleicht. Denn bis jetzt hat hier niemand hier auf das Slicing-
Problem hingewiesen.
Wenn ein Object per Value übergeben wird, dann wird nicht nur eine
Copy erzeugt,
sondern eine Kopie des angegeben statischen Typs.
Wird einer Funktion ein A-Objekt übergeben und die Klasse B ist von A
abgeleitet,
dann kann dieser Funktion auch logischerweise eine Instanz von B
übergeben werden.
Wenn diese Übergabe per Value erfolgt, dann ist innerhalb von dieser
Funktion eben
nur ein A-Objekt. Da nützt alles virtual nix...
Folgendes Beispiel:
#include <cstdlib>
#include <iostream>
class A{
public:
A(){std::cout << "A::A()" << std::endl; }
~A(){std::cout << "A::~A()" << std::endl; }
virtual void f() const{std::cout << "A::f()" << std::endl; }
};
class B : public A{
public:
B(){std::cout << "B::B()" << std::endl; }
~B(){std::cout << "B::~B()" << std::endl; }
virtual void f() const{std::cout << "B::f()" << std::endl; }
};
void function1(A a){
std::cout << "function1" << std::endl;
a.f();
}
void function2(const A& a){
std::cout << "function2" << std::endl;
a.f();
}
int main(int argc, char *argv[])
{
B b;
function1(b); //hier wird implizit der Copycontructor A(b)
aufgerufen
function2(b); //hier nicht, hier bleibt das b so wie es ist
erhalten...
std::cout << "Fertig!" << std::endl;
char c;
std::cin >> c;
return 0;
} |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|