 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Alex Muffmolch Guest
|
Posted: Tue Nov 11, 2003 12:27 pm Post subject: Rückgabewert Refernz oder Kopie |
|
|
Hallo,
ich hätte hier eine Stilfrage...
int main()
{
Matrix A(3,3);
Matrix B(3,3);
Matrix C = A*B; //Aufruf1
(A*B).print(cout); //Aufruf2
return 0;
}
In den folgenden Matrzien seien alle notwendigen
Kopierkonstruktoren,Zuweisungsoperatoren und Deskruktoren
überschrieben. Die Klasse Matrix verfügt über dynamische Elemente.
1.Version
class Matrix
{
...
Matrix& operator*(Matrix& src) //Multiplikation zweier Matrizen
{
...
Matrix *M = new Matrix(rows,cols)
...
return *M;
}
private:
double *m_Data;
};
hier wird intern ein neues, dynmaisches Matrix Objekt angelegt und per
Referenz zurückgegeben
2.Version
class Matrix
{
...
Matrix operator*(Matrix& src) //Multiplikation zweier Matrizen
{
...
Matrix M(rows,cols)
...
return M;
}
private:
double *m_Data;
};
hier wird intern ein neues, automatisches Matrix Objekt angelegt und
dessen Kopie zurückgegeben
Vorteil Variante1:
bei Aufruf1 (C=A*B) wird C direkt die Adresse der neu erstellten
Matrix M zugewiesen.
bei Variante2 würde bei Rückkehr der operator*-Methode zuerst eine
Kopie von M
erstellt, dann M gelöscht und zu guter letzt die Kopie C zugewiesen
werden werden (-> doppelter Speicheraufwand bei Var2 und schlechtere
Laufzeit).
Nachteil Variante1:
weist man die Rückgabematrix M KEINER variabel zu (z.B. Aufruf2_
(A*B).print(cout); ), dann würde ein peicherlag entstehen, weil der
von M belegte Speicher nicht freigegeben wird.
in Variante2 würde die Kopie von M automatisch gelöscht werden.
ALSO:
sollte man deshalb eher auf Nummer sicher gehen und Variante2
benutzen?
Was sagt ihr dazu?
Gruß,
Sören
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Tue Nov 11, 2003 12:59 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Alex Muffmolch wrote:
| Quote: |
Hallo,
ich hätte hier eine Stilfrage...
int main()
{
Matrix A(3,3);
Matrix B(3,3);
Matrix C = A*B; //Aufruf1
(A*B).print(cout); //Aufruf2
return 0;
}
In den folgenden Matrzien seien alle notwendigen
Kopierkonstruktoren,Zuweisungsoperatoren und Deskruktoren
überschrieben. Die Klasse Matrix verfügt über dynamische Elemente.
1.Version
class Matrix
{
...
Matrix& operator*(Matrix& src) //Multiplikation zweier Matrizen
{
...
Matrix *M = new Matrix(rows,cols)
...
return *M;
}
private:
double *m_Data;
};
hier wird intern ein neues, dynmaisches Matrix Objekt angelegt und per
Referenz zurückgegeben
|
Keine so gute Idee. Zumal der Returntyp ueberhaupt nicht darauf schliessen
laesst, das hier dynamische Allokierung im Spiel ist.
| Quote: |
2.Version
class Matrix
{
...
Matrix operator*(Matrix& src) //Multiplikation zweier Matrizen
{
...
Matrix M(rows,cols)
...
return M;
}
private:
double *m_Data;
};
hier wird intern ein neues, automatisches Matrix Objekt angelegt und
dessen Kopie zurückgegeben
Vorteil Variante1:
bei Aufruf1 (C=A*B) wird C direkt die Adresse der neu erstellten
Matrix M zugewiesen.
|
Aeehm. Nein.
Das Objekt C existiert schon. Lediglich die Innereien von A*B werden
dem C Objekt zugewiesen. Das returnierte Objekt ist danach fuer
dich nicht mehr zugaenglich: -> Du hast soeben ein Speicherleck
produziert.
| Quote: | bei Variante2 würde bei Rückkehr der operator*-Methode zuerst eine
Kopie von M
erstellt, dann M gelöscht und zu guter letzt die Kopie C zugewiesen
werden werden (-> doppelter Speicheraufwand bei Var2 und schlechtere
Laufzeit).
|
Lass das mal das Problem des Compilers sein.
| Quote: |
Nachteil Variante1:
weist man die Rückgabematrix M KEINER variabel zu (z.B. Aufruf2_
(A*B).print(cout); ), dann würde ein peicherlag entstehen, weil der
von M belegte Speicher nicht freigegeben wird.
|
Das entsteht so wie Du's gemacht hast auf jeden Fall.
Die einzige Chance das Leck zu umgehen, waere:
Matrix* C = &(A*B);
...
delete C;
Und dann ist das Ganze auf einmal gar nicht mehr so elegant :-)
Merke: jedes new benoetigt ein delete (ausser wenn smart-Pointer
im Spiel sind). Hast Du das nicht -> Speicher Leck.
| Quote: | in Variante2 würde die Kopie von M automatisch gelöscht werden.
ALSO:
sollte man deshalb eher auf Nummer sicher gehen und Variante2
benutzen?
|
Du sollst *immer* auf Nummer sicher gehen. Ein paar Prozent Laufzeit
sind heutzutage kein Thema mehr. Ein Programm das beim Kunden aber
einfach sang und klaglos (meist nichtreproduzierbar) abschmiert,
*ist* aber ein Thema.
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
André Pönitz Guest
|
Posted: Tue Nov 11, 2003 1:01 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Alex Muffmolch <muffmolch (AT) gmx (DOT) de> wrote:
| Quote: | In den folgenden Matrzien seien alle notwendigen
Kopierkonstruktoren,Zuweisungsoperatoren und Deskruktoren
überschrieben. Die Klasse Matrix verfügt über dynamische Elemente.
1.Version
class Matrix
{
...
Matrix& operator*(Matrix& src) //Multiplikation zweier Matrizen
{
...
Matrix *M = new Matrix(rows,cols)
...
return *M;
}
private:
double *m_Data;
};
hier wird intern ein neues, dynmaisches Matrix Objekt angelegt und per
Referenz zurückgegeben
2.Version
class Matrix
{
...
Matrix operator*(Matrix& src) //Multiplikation zweier Matrizen
{
...
Matrix M(rows,cols)
...
return M;
}
private:
double *m_Data;
};
|
3. Version:
Matrix operator*(Matrix const &, Matrix const &)
{
...
}
| Quote: | Vorteil Variante1:
bei Aufruf1 (C=A*B) wird C direkt die Adresse der neu erstellten
Matrix M zugewiesen.
|
?
C ist keine Zeiger, kann also schlecht 'ne Adresse zugewiesen bekommen.
| Quote: | bei Variante2 würde bei Rückkehr der operator*-Methode zuerst eine
Kopie von M
erstellt, dann M gelöscht und zu guter letzt die Kopie C zugewiesen
werden werden (-> doppelter Speicheraufwand bei Var2 und schlechtere
Laufzeit).
Nachteil Variante1:
weist man die Rückgabematrix M KEINER variabel zu (z.B. Aufruf2_
(A*B).print(cout); ), dann würde ein peicherlag entstehen, weil der
von M belegte Speicher nicht freigegeben wird.
|
Das entsteht auch wenn Du's zuweist. Oder wo steht das 'delete' dass zu
dem 'new' gehoiert.
| Quote: | in Variante2 würde die Kopie von M automatisch gelöscht werden.
ALSO:
sollte man deshalb eher auf Nummer sicher gehen und Variante2
benutzen?
Was sagt ihr dazu?
|
Variante 2 hat immerhin den Vorteil, dass sie funktioniert.
Huebscher waere natuerlich, nur operator*=() _in_ der Klasse zu
definieren und die Multiplikation mit einer freien Funktion zu machen.
Andre'
--
Those who desire to give up Freedom in order to gain Security, will not have,
nor do they deserve, either one. (T. Jefferson or B. Franklin or both...)
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Andreas Huennebeck Guest
|
Posted: Tue Nov 11, 2003 1:09 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Karl Heinz Buchegger wrote:
| Quote: | Alex Muffmolch wrote:
2.Version
class Matrix
{
...
Matrix operator*(Matrix& src) //Multiplikation zweier Matrizen
{
...
Matrix M(rows,cols)
...
return M;
}
private:
double *m_Data;
};
hier wird intern ein neues, automatisches Matrix Objekt angelegt und
dessen Kopie zurückgegeben
Vorteil Variante1:
bei Aufruf1 (C=A*B) wird C direkt die Adresse der neu erstellten
Matrix M zugewiesen.
Aeehm. Nein.
Das Objekt C existiert schon. Lediglich die Innereien von A*B werden
dem C Objekt zugewiesen.
|
Richtig.
| Quote: | Das returnierte Objekt ist danach fuer
dich nicht mehr zugaenglich: -> Du hast soeben ein Speicherleck
produziert.
|
Nein, kein Speicherleck, da auf dem Stack erzeugt.
| Quote: | Du sollst *immer* auf Nummer sicher gehen. Ein paar Prozent Laufzeit
sind heutzutage kein Thema mehr. Ein Programm das beim Kunden aber
einfach sang und klaglos (meist nichtreproduzierbar) abschmiert,
*ist* aber ein Thema.
|
Ack.
Tschau
Andreas
--
Andreas Hünnebeck | email: [email]ah (AT) despammed (DOT) com[/email]
----- privat ---- | www : http://www.huennebeck-online.de
Fax/Anrufbeantworter: 0721/151-284301 o. 0180/50525-5232659 (24 Pfg/Min)
SMS: D1=72617 D2=0172/7366-042 E-Plus=0177/7934-396 Viag=0179/2029-894
GPG-Key: http://www.huennebeck-online.de/public_keys/andreas.asc
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Christoph Rabel Guest
|
Posted: Tue Nov 11, 2003 2:05 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Andreas Huennebeck wrote:
| Quote: | Karl Heinz Buchegger wrote:
Nein, kein Speicherleck, da auf dem Stack erzeugt.
|
Ah, dann also eine hängende Referenz, noch schlimmer...
mfg
Christoph
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Tue Nov 11, 2003 2:24 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Andreas Huennebeck wrote:
| Quote: |
Vorteil Variante1:
bei Aufruf1 (C=A*B) wird C direkt die Adresse der neu erstellten
Matrix M zugewiesen.
Aeehm. Nein.
Das Objekt C existiert schon. Lediglich die Innereien von A*B werden
dem C Objekt zugewiesen.
Richtig.
Das returnierte Objekt ist danach fuer
dich nicht mehr zugaenglich: -> Du hast soeben ein Speicherleck
produziert.
Nein, kein Speicherleck, da auf dem Stack erzeugt.
|
Ich rede nicht vom auto-Objekt C, ich rede vom Objekt das
innerhalb des operator* mittels new erzeugt worden ist.
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Tue Nov 11, 2003 2:29 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Andreas Huennebeck wrote:
| Quote: |
Aeehm. Nein.
Das Objekt C existiert schon. Lediglich die Innereien von A*B werden
dem C Objekt zugewiesen.
Richtig.
Das returnierte Objekt ist danach fuer
dich nicht mehr zugaenglich: -> Du hast soeben ein Speicherleck
produziert.
Nein, kein Speicherleck, da auf dem Stack erzeugt.
|
Dir Matrix C, ja.
Aber was ist mit dem im operator* mittels new erzeugtem Objekt?
Da es nach der Initialisierung von C keinen Pointer mehr drauf
gibt ...
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Christoph Rabel Guest
|
Posted: Tue Nov 11, 2003 2:35 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Christoph Rabel wrote:
| Quote: | Andreas Huennebeck wrote:
Karl Heinz Buchegger wrote:
Nein, kein Speicherleck, da auf dem Stack erzeugt.
Ah, dann also eine hängende Referenz, noch schlimmer...
|
Hoppla, hab mir die Implementierung nicht angeschaut und gedacht, du
machst sowas
int foo()
{
int i = 0;
return &i;
}
Doch Speicherleck.
lg
odie
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Albrecht Fritzsche Guest
|
Posted: Tue Nov 11, 2003 2:43 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Alex Muffmolch wrote:
| Quote: | Hallo,
ich hätte hier eine Stilfrage...
|
Ich glaube, allgemein anerkannte Stil schliesst die beiden folgenden
Punkte ein
- as simple as possible
--> keine unnuetzen dynamisch allokierten/deallokierten Member
- increased class encapsulation
--> keine Memberfunktionen, wenn diese auch stand-alone sein koennen
www.cuj.com/documents/s=8042/cuj0002meyers/
| Quote: | ALSO:
sollte man deshalb eher auf Nummer sicher gehen und Variante2
benutzen?
Was sagt ihr dazu?
|
Ich wuerde keine der beiden Varianten verwenden. Die von André gepostete
| Quote: | 3. Version:
Matrix operator*(Matrix const &, Matrix const &)
{
...
}
|
ist da weit ueberlegen. Zum einen haelt sie Deine Matrix-Klasse
ueberschaubar klein und frei von (dort) unnuetzen Fkt. Zum anderen
duerfte sie Deinen Varianten in Sachen Performance ueberlegen sein.
Falls Du Code wie
Matrix C = A * B;
hast, wird mittels der (IIRC) "Return Value Optimization" sogar meist
die Kopie vermieden.
| Quote: | private:
double *m_Data;
};
|
Zudem sehe ich noch keinen Grund, warum Du dynamisch ein double*-Member
fuer jedes Objekt allokieren/deallokieren willst. Dies macht den Code
nicht nur unnoetig komplex, sondern wird im Zweifelsfalle auch Deine
Performance ruinieren.
Ali
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Alex Muffmolch Guest
|
Posted: Wed Nov 12, 2003 4:57 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Ich wuerde keine der beiden Varianten verwenden. Die von André
gepostete
| Quote: | 3. Version:
Matrix operator*(Matrix const &, Matrix const &)
{
...
}
ist da weit ueberlegen. Zum einen haelt sie Deine Matrix-Klasse
ueberschaubar klein und frei von (dort) unnuetzen Fkt. Zum anderen
duerfte sie Deinen Varianten in Sachen Performance ueberlegen sein.
Falls Du Code wie
Matrix C = A * B;
hast, wird mittels der (IIRC) "Return Value Optimization" sogar meist
die Kopie vermieden.
private:
double *m_Data;
};
also eine globale operatorüberladung, oder!? |
schreibt man die auch einfach ins headerfile? (hab ich bisher noch nie
gemacht...)
| Quote: | Zudem sehe ich noch keinen Grund, warum Du dynamisch ein double*-Member
fuer jedes Objekt allokieren/deallokieren willst. Dies macht den Code
nicht nur unnoetig komplex, sondern wird im Zweifelsfalle auch Deine
Performance ruinieren.
|
naja, die dynamischen felder verwende ich um die matrix grösse zur
laufzeit zu verändern und auch erst festzulegen... wie soll ich denn
sonst verschieden grosse matrizen erstellen??
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Alex Muffmolch Guest
|
Posted: Wed Nov 12, 2003 5:00 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
| Quote: | Variante 2 hat immerhin den Vorteil, dass sie funktioniert.
Huebscher waere natuerlich, nur operator*=() _in_ der Klasse zu
definieren und die Multiplikation mit einer freien Funktion zu machen.
Andre'
|
der operator *= existiert bereits...
die freie fkt werde ich gleich hinzubasteln!!!
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Alex Muffmolch Guest
|
Posted: Wed Nov 12, 2003 5:31 pm Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
okay habe nun folgende funktionalität hinzugefügt:
#ifndef _MMM_M
#define _MMM_M
class Matrix{
...
Matrix& operator*=(const Matrix& src)
{
//if(this->GetCols() != src.GetRows()) -> exception
Matrix C(this->m_Rows,src.GetCols());
int ARow,BCol,length;
for(ARow=0;ARow<this->m_Rows;ARow++){
for(BCol=0;BCol<src.GetCols();BCol++){
C(ARow,BCol) = 0.0;
for(length=0;length
C(ARow,BCol)+=(*this)(ARow,length) * src(length,BCol);
}
}
}
return (*this)=C;
};
};
Matrix operator*(const Matrix& A, const Matrix& B)
{
Matrix temp(A);
temp*=B;
return temp;
}
#endif
stimmt das so? insbesondere die operator*= Überladung?
denn irgendwas stimmt noch nicht (seit des globalen operators):
Der Linker gibt nun immer den Fehlercode:
wvtransformator2d.obj : error LNK2005: "class LaMatrix2D __cdecl
operator*(class LaMatrix2D const &,class LaMatrix2D const &)"
(??D@YA?AVLaMatrix2D@@ABV0@0@Z) bereits in main.obj definiert
wobei ich die headerdatei MMM.M in der main.cpp und
wvtransformator2d.h eingebunden habe?
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Alex Muffmolch Guest
|
Posted: Thu Nov 13, 2003 9:01 am Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
| Quote: | Der Linker gibt nun immer den Fehlercode:
wvtransformator2d.obj : error LNK2005: "class LaMatrix2D __cdecl
operator*(class LaMatrix2D const &,class LaMatrix2D const &)"
(??D@YA?AVLaMatrix2D@@ABV0@0@Z) bereits in main.obj definiert
wobei ich die headerdatei MMM.M in der main.cpp und
wvtransformator2d.h eingebunden habe?
|
müssen globale funktionen im header immer mit inline definiert werden,
wenn sie dort und nicht in ner cpp datei ausprogrammiert werden?
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Thu Nov 13, 2003 10:03 am Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Alex Muffmolch wrote:
| Quote: |
okay habe nun folgende funktionalität hinzugefügt:
#ifndef _MMM_M
#define _MMM_M
class Matrix{
...
Matrix& operator*=(const Matrix& src)
{
//if(this->GetCols() != src.GetRows()) -> exception
Matrix C(this->m_Rows,src.GetCols());
int ARow,BCol,length;
for(ARow=0;ARow<this->m_Rows;ARow++){
for(BCol=0;BCol<src.GetCols();BCol++){
C(ARow,BCol) = 0.0;
for(length=0;length
C(ARow,BCol)+=(*this)(ARow,length) * src(length,BCol);
}
}
}
return (*this)=C;
};
};
Matrix operator*(const Matrix& A, const Matrix& B)
{
Matrix temp(A);
temp*=B;
return temp;
}
#endif
stimmt das so? insbesondere die operator*= Überladung?
|
Sieht gut aus.
| Quote: |
denn irgendwas stimmt noch nicht (seit des globalen operators):
Der Linker gibt nun immer den Fehlercode:
wvtransformator2d.obj : error LNK2005: "class LaMatrix2D __cdecl
operator*(class LaMatrix2D const &,class LaMatrix2D const &)"
(??D@YA?AVLaMatrix2D@@ABV0@0@Z) bereits in main.obj definiert
wobei ich die headerdatei MMM.M in der main.cpp und
wvtransformator2d.h eingebunden habe?
|
Ueberleg mal:
Wenn Du den Header in main.cpp includierst dann wird dort eine
Funktion 'operator*' erzeugt, denn schliesslich ist sie ja durch
den Header reingezogen worden. Inkludierst Du den Header noch
in einem anderem *.cpp File, dann wird dort ebenfalls eine
Funktion 'operator*' erzeugt, sie steht ja schliesslich im Header File.
-> Der Linker hat also 2 Implementierungen und weiss nicht welche
denn nun gilt.
#include macht nichts geheimnisvolles. Es ist eine reine Textsubstitution.
So als ob Du in Deinem Text Editor die Zeile
#include "irgendwas.h"
mit dem Inhalt der Datei "irgendwas.h" ersetzen wuerdest.
Du schreibst:
test.h
******
int foo2();
int foo()
{
return 0;
}
test1.cpp
*********
#include "test.h"
int main()
{
foo()
foo2();
}
test2.cpp
*********
#include "test.h"
int foo2()
{
return 1;
}
Nachdem der Preprozessor gelaufen ist, kriegt der Compiler
aber was ganz anderes zu sehen, er kriegt:
test1_.cpp
**********
int foo2();
int foo()
{
return 0;
}
int main()
{
foo();
foo2();
}
und test2_.cpp
**********
int foo2();
int foo()
{
return 0;
}
int foo2()
{
return 1;
}
Linkst Du nun die Uebersetzungen von test1_.cpp und test2_.cpp
so ist klar, das es 2 Implementierungen von foo() gibt. Und genau
deswegen meckert der Linker.
Abhilfe:
Entweder verschiebst Du die Imlpementierung der Funktion in ein
*.cpp File (und compilierst damit den Funktionsrumpf nur einmal),
oder Du machst die Funktion inline:
inline Matrix operator*( const Matrix& A, const Matrix & B )
{
Matrix temp( A );
temp *= B;
return temp;
}
Da die Funktion nur kurz ist stehen die Chancen nicht schlecht,
das Dein Compiler die inline-Aufforderung auch umsetzt. Und selbst
wenn nicht, ist es das Problem des Compilers dafuer zu sorgen, dass
der Funktionsrumpf nur einmal existiert.
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Thu Nov 13, 2003 10:10 am Post subject: Re: Rückgabewert Refernz oder Kopie |
|
|
Alex Muffmolch wrote:
| Quote: |
Der Linker gibt nun immer den Fehlercode:
wvtransformator2d.obj : error LNK2005: "class LaMatrix2D __cdecl
operator*(class LaMatrix2D const &,class LaMatrix2D const &)"
(??D@YA?AVLaMatrix2D@@ABV0@0@Z) bereits in main.obj definiert
wobei ich die headerdatei MMM.M in der main.cpp und
wvtransformator2d.h eingebunden habe?
müssen globale funktionen im header immer mit inline definiert werden,
wenn sie dort und nicht in ner cpp datei ausprogrammiert werden?
|
Wenn Du die Header Datei in mehreren Uebersetzungseinheiten (sprich *.cpp Files)
verwenden willst: ja.
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| 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
|
|