Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Call by reference, schön und gut, aber...

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] > 2 < [ 3 ]
010
16.08.2006, 10:15 Uhr
~Blubber2063
Gast


Trotzdem solltest du auf ihn hören, bei methoden kann man mit entsprechendem Verweis darauf das der Speicher freigegeben werden soll mit new arbeiten, aber es ist meist eh besser eines der Objekte zu verändern, da du sonst immer ein neues Objekt erzeugst, sei es dynamisch oder statisch.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
16.08.2006, 10:27 Uhr
ao

(Operator)



Zitat von ~Blubber2063:
... aber es ist meist eh besser eines der Objekte zu verändern, da du sonst immer ein neues Objekt erzeugst ...

Beim Additions-Operator?!? Du meinst, ein Ausdruck wie

c = a + b

soll den Seiteneffekt haben, dass entweder a oder b verändert wird? Das ist eindeutig falsches Verhalten, kein Mensch würde das verstehen.

Du darfst nicht die Wirklichkeit den softwaretechnischen Gegebenheiten anpassen, sondern die Software muss die Wirklichkeit nachbilden. Und bei c = a + b ist es nun mal so, dass ein neues Objekt entsteht, also muss der +-Operator das auch leisten, sonst ist er irgendwas, aber kein +-Operator. Wenn das teuer ist - Pech, aber so ist das Leben.

Gruß,
ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
16.08.2006, 10:40 Uhr
~Blubber2063
Gast


Das ist ne andere Kiste ao, Operatorüberladung ist ja eh umstritten. Du hast schon recht man sollte die Operatoren so formulieren das sie verständlich sind, allerdings ist ein Array + ein anderes auch nicht unbedingt verständlich und es gibt ja sowas wie doku und den operatorumpf, der dann natürlich keinen Rückgabewert haben sollte. In moderneren Sprachen gibts diese Probleme ja dank GC sowieso nicht mehr, aber ich wollte auch nur mal deutlich machen das es sinnvoll ist von Anfang an halbwegs laufzeiteffektiv zu arbeiten.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
16.08.2006, 10:52 Uhr
Yadgar



High!


Zitat von ao:
[quote ~Blubber2063]... aber es ist meist eh besser eines der Objekte zu verändern, da du sonst immer ein neues Objekt erzeugst ...

Beim Additions-Operator?!? Du meinst, ein Ausdruck wie

c = a + b

soll den Seiteneffekt haben, dass entweder a oder b verändert wird? Das ist eindeutig falsches Verhalten, kein Mensch würde das verstehen.
[/quote]

Genau das war ja auch mein ursprüngliches Problem mit der Referenzrückgabe... und Blubber2063 selbst hat mir ja zur Anforderung mit new geraten!

Bis bald im Khyberspace!

Yadgar
--
Flagmaker - ein Programmier-Blog
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
16.08.2006, 11:00 Uhr
(un)wissender
Niveauwart


Hallo, ich habe dir mal ein Beispiel implementiert, mit einfachem Code.
Du solltest dich wirklich dringend daran orientieren, wenn ich nichts übersehen haben sollte (kommt selten vor, ist diese Klasse für deine Übungen genau die richtige.


C++:
//hpp
#include <iosfwd>
#include <cstdlib>

class FixedArray
{
public:
     explicit FixedArray(int length);
     FixedArray(FixedArray const& f);
     ~FixedArray();
     FixedArray& operator= (FixedArray const& f);
     FixedArray& operator+=(FixedArray const & f);
     int & operator[]( std::size_t index);
     int const& operator[]( std::size_t index) const;
     std::size_t length() const;    
      
private:
     void assign(FixedArray const& f);
    
     std::size_t const _length;
     int * _mem;
};  

std::ostream& operator<<(std::ostream &out, FixedArray const& f);
FixedArray const operator+(FixedArray const & f, FixedArray const & s);  

//cpp
//#include "FixedArray.hpp"
#include <algorithm>
#include <stdexcept>
#include <iostream>

std::ostream& operator<<(std::ostream &out, FixedArray const& f)
{
    for(std::size_t i = 0; i < f.length(); ++i)
    {
        out <<  f[i] << ' ';
    }
    return  out;  
}
    
FixedArray::FixedArray(int length)
:   _length(length), _mem(new int[length])
{
    std::fill(_mem, _mem + length, 0);
}

FixedArray::FixedArray(FixedArray const& f)
:   _length(f._length), _mem(0)
{
   assign(f);
}  

FixedArray::~FixedArray()
{
    delete [] _mem;
}

FixedArray& FixedArray::operator= (FixedArray const& f)
{
    assign(f);
    return *this;
}

FixedArray& FixedArray::operator+=(FixedArray const & f)
{
     if(f.length() != length()) throw std::range_error("indexes not matching");
     for(std::size_t i = 0; i < f.length(); ++i)
     {
         _mem[i] += f._mem[i];
     }
     return *this;  
}    
    
FixedArray const operator+(FixedArray const & f, FixedArray const & s)
{
     FixedArray temp(f);
     return temp += s;
}
    
int & FixedArray::operator[]( std::size_t index)
{
    if(index >= _length) throw std::overflow_error("index too big");
    return _mem[index];
}  
  
int const& FixedArray::operator[]( std::size_t index) const
{
    if(index >= _length) throw std::overflow_error("index too big");
    return _mem[index];
}    

std::size_t FixedArray::length() const
{
    return _length;
}

void FixedArray::assign(FixedArray const& f)
{
    int * mem = new int[f.length()];
    std::copy(f._mem, f._mem + f.length(), mem);
    delete [] _mem;
    _mem = mem;
}        

int main()
{
    FixedArray array1(3);
    std::cout << "Leeres array:\n" << array1;
    array1[0] = 2;
    array1[1] = 2;
    array1[2] = 2;
    std::cout << "\nVolles erstes array:\n" << array1;
    try
    {
        array1[3] = 2;  
    }  
    catch(std::overflow_error const & ex)
    {
         std::cout << "\nZugriffsfehler:\n" << ex.what();
    }  
    FixedArray array2(3);  
    array2[0] = 2;
    array2[1] = 2;
    array2[2] = 2;
    std::cout << "\nZweites array:\n" << array2;
    std::cout << "\nNach Addition:\n" << array1 + array2;
}    



--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 16.08.2006 um 11:26 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
16.08.2006, 11:22 Uhr
ao

(Operator)



Zitat von ~Blubber2063:
allerdings ist ein Array + ein anderes auch nicht unbedingt verständlich

Wenn das Array als Vektor von Zahlen aufgefasst wird (Vektor im mathematischen Sinn, nicht std::vector), dann finde ich einen +-Operator schon verständlich. Was anderes als elementweises Addieren würde mir nicht einleuchten.

Zitat:
und es gibt ja sowas wie doku und den operatorumpf,

... und in die Doku willst du reinschreiben "Achtung, dieser Operator ist kein + im üblichen Sinn, weil er auch den ersten (oder zweiten) Summanden verändert"? Das kannst du nicht bringen, damit machst du dich zum Gespött.

Und im Operatorrumpf lesen die Leute auch erst nach, wenn das Problem da ist. Dann debuggen sie, finden den Fehler (denn es ist einer) und hauen ihn dir um die Ohren.

Zitat:
das es sinnvoll ist von Anfang an halbwegs laufzeiteffektiv zu arbeiten.

Kleinere Abstriche am richtigen Verhalten müssen dabei in Kauf genommen werden, ja?

Ein Operator, der das Falsche tut, ist *überhaupt nicht* laufzeiteffektiv, ob er das nun schnell oder langsam macht.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
16.08.2006, 12:16 Uhr
~DoppleR
Gast


Andere Frage: K"onnte man das tempor"are Objekt im operator+ static machen? Etwa so:

C++:
FixedArray const operator+(FixedArray const & f, FixedArray const & s)
{
     static FixedArray temp;
     temp = f;
     return temp += s;
}


Bzw. welche Probleme k"onnte es geben? Die statische Variable sollte ja auch nach Ende der Funktion existieren, beim n"achsten Aufruf ist sie ja auch bekannt?

Bei konkurierenden Zugriffen sehe ich auch kein Problem, weil die Funktion sich nicht selbst aufruft.

W"urde das etwas bringen (die Laufzeit betreffend), also falls man fast immer fixedArrays der gleichen Gr"osse hat?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
16.08.2006, 12:28 Uhr
~DoppleR
Gast


Sorry, ich meinte nat"urlich

C++:
FixedArray const& operator+(FixedArray const & f, FixedArray const & s)
{
     static FixedArray temp;
     temp = f;
     return temp += s;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
018
16.08.2006, 13:15 Uhr
ao

(Operator)



Zitat von ~DoppleR:
Andere Frage: K"onnte man das tempor"are Objekt im operator+ static machen?

Was ist damit gewonnen? Hier ist (un)wissenders Operator:

C++:
FixedArray const operator+(FixedArray const & f, FixedArray const & s)
{
     FixedArray temp(f);   // lokales Objekt copy-konstruieren
     return temp += s;    // +=-Operation und Rückgabe als Kopie
}

Hier ist deiner:

C++:
FixedArray const& operator+(FixedArray const & f, FixedArray const & s)
{
     static FixedArray temp;  // Default-Konstruktion (ein einziges Mal)
     temp = f;  // Zuweisung (praktisch identisch zu Copy-Konstruktion oben)
     return temp += s; // +=-Operation und Rückgabe als Referenz
}

Wenn das Objekt, in dem das Ergebnis gespeichert wird, ebenfalls eine Referenz ist, sparst du die Rückgabe-Kopie ein. Dafür wird jeder nachfolgende Aufruf des Operators hintenrum dein altes Ergebnis verändern, weil du nur die Referenz hältst (merke: Referenzen sind wie Pointer, sie sehen nur nicht so aus). Nicht brauchbar.

Dieser Nachteil kommt nur dann *nicht* zum Tragen, wenn das Ergebnis der Addition gar nicht gespeichert werden soll, sondern nur an Ort und Stelle (z.B. für einen Vergleich) ausgewertet und danach wieder vergessen wird. Aber das wird kein Anwender auseinanderklamüsern.

Wenn das Objekt keine Referenz ist, sondern ein echtes FixedArray, dann findet beim Zuweisen des Ergebnisses (Objekt = Referenz) eine Kopieraktion statt, und damit bewirken beide Operatoren unterm Strich dieselben Aktionen.

Dein Operator hat zusätzlich den Nachteil, nicht threadfest zu sein.

Gruß,
ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
019
16.08.2006, 13:43 Uhr
~DoppleR
Gast


Danke, ao.
Ich glaube ich hatte nicht verstanden, wann genau kopiert wird. Ist jetzt viel klarer .
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 < [ 3 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: