Wann nehme ich Objekt, Zeiger oder Referez?
-
Werner Salomon schrieb:
template< typename F > void langFunc( const F& fktr, .. weiter Paramter ) { // .. viel Code fktr( .. ); // <- hier wird was verändert // .. noch mal Code } // der Aufruf CMyClass a; langFunc( boost::bind( &CMyClass::Meth1, &a, usw. ), .. weitere Parameter );
warum soll man hier boost::bind verwenden?
-
ich kenne da einen, der hat ne ganz komische meinung dazu.
hier rät er ganz allgemein von referenzen als andere namen ab.
http://www.volkard.de/vcppkold/referenzen.htmlhier rät er davon ab, referenzen als funktionsparameter zu nehmen.
http://www.volkard.de/vcppkold/call_by_reference.htmlund hier sagt er, daß man aber const-referenzen als parameter ruhig und viel benutzen soll.
http://www.volkard.de/vcppkold/constreferenzen.htmlist irgendwie schlimm, wie sich der über eure einfache argumentation wie "-> ist nicht schön" oder "weil referenzen nicht 0 haben können, sind sie besser" hinwegsetzt. und das schon seit 5 jahren.
-
volkard schrieb:
ich kenne da einen, der hat ne ganz komische meinung dazu.
hier rät er ganz allgemein von referenzen als andere namen ab.
http://www.volkard.de/vcppkold/referenzen.htmlhier rät er davon ab, referenzen als funktionsparameter zu nehmen.
http://www.volkard.de/vcppkold/call_by_reference.htmlund hier sagt er, daß man aber const-referenzen als parameter ruhig und viel benutzen soll.
http://www.volkard.de/vcppkold/constreferenzen.htmlist irgendwie schlimm, wie sich der über eure einfache argumentation wie "-> ist nicht schön" oder "weil referenzen nicht 0 haben können, sind sie besser" hinwegsetzt. und das schon seit 5 jahren.
Auch "der" muss ja nicht immer und überall Recht haben.
-
Man sollte nicht die Moeglichkeiten der NULL-Referenz unterschaetzen. Nehmen wir mal folgende Methode:
MyObject *MyClass::GetCurrentReference (ErrorHandler *pErrorhandler = NULL)
{
if ((pCurrentReference == NULL) && (pErrorhandler != NULL))
{
pErrorhandler->WriteError ("No Reference Pointer\n");
throw (ERROR_NO_REFERENCE); //irgentwo def.
}return pCurrentReference;
}Diese Zeigt so, ohne Ueberlagerung jeweils ein anderes Verhalten.
-
ich denke "der" ist ein nup.
-
Redhead schrieb:
volkard schrieb:
ich kenne da einen, der hat ne ganz komische meinung dazu.
hier rät er ganz allgemein von referenzen als andere namen ab.
http://www.volkard.de/vcppkold/referenzen.htmlhier rät er davon ab, referenzen als funktionsparameter zu nehmen.
http://www.volkard.de/vcppkold/call_by_reference.htmlund hier sagt er, daß man aber const-referenzen als parameter ruhig und viel benutzen soll.
http://www.volkard.de/vcppkold/constreferenzen.htmlist irgendwie schlimm, wie sich der über eure einfache argumentation wie "-> ist nicht schön" oder "weil referenzen nicht 0 haben können, sind sie besser" hinwegsetzt. und das schon seit 5 jahren.
Auch "der" muss ja nicht immer und überall Recht haben.
Nein sicher nicht. Bringt aber im Gegensatz zu den anderen Argumente.
mfg
v R
-
virtuell Realisticer schrieb:
Redhead schrieb:
volkard schrieb:
ich kenne da einen, der hat ne ganz komische meinung dazu.
hier rät er ganz allgemein von referenzen als andere namen ab.
http://www.volkard.de/vcppkold/referenzen.htmlhier rät er davon ab, referenzen als funktionsparameter zu nehmen.
http://www.volkard.de/vcppkold/call_by_reference.htmlund hier sagt er, daß man aber const-referenzen als parameter ruhig und viel benutzen soll.
http://www.volkard.de/vcppkold/constreferenzen.htmlist irgendwie schlimm, wie sich der über eure einfache argumentation wie "-> ist nicht schön" oder "weil referenzen nicht 0 haben können, sind sie besser" hinwegsetzt. und das schon seit 5 jahren.
Auch "der" muss ja nicht immer und überall Recht haben.
Nein sicher nicht. Bringt aber im Gegensatz zu den anderen Argumente.
mfg
v RDa seine Argumente, für mich, nicht nachvollziehbar sind, sind das somit,
für mich, auch keine Argumente.
-
gasi schrieb:
Werner Salomon schrieb:
CMyClass a; langFunc( boost::bind( &CMyClass::Meth1, &a, usw. ), .. weitere Parameter );
warum soll man hier boost::bind verwenden?
Muss man nicht. Das ist nur ein Beispiel. Der Funktor ist eine Möglichkeit die Schnittstelle zwischen der Klasse CMyClass und der Funktion langFunc zu reduzieren.
-
www.spam.geloescht
-
langFunc( boost::bind( &CMyClass::Meth1, &a, usw. ), .. weitere Parameter );
was ist hier der input an boost::bind und was das output von boost::bind...zugleich der input an langFunc??!?
-
gasi schrieb:
langFunc( boost::bind( &CMyClass::Meth1, &a, usw. ), .. weitere Parameter );
was ist hier der input an boost::bind und was das output von boost::bind...zugleich der input an langFunc??!?
Angenommen die Klasse CMyClass hat eine Methode Meth1, die einen int als Parameter aufnimmt.
CMyClass::Meth1( int x );
mit einem Aufruf von Meth1 wird das Objekt der Klasse CMyClass verändert, und genau das soll irgendwo innerhalb von langFunc geschehen. Dann gibt's die Möglichkeit, der Funktion langFunc eine Referenz oder einen Pointer auf das Objekt der Klasse CMyClass mitzugeben und langFunc ruft dann die Methode auf.
void langFunc( CMyClass& a, ..Rest interesiert hier nicht ) { // bla bla a.Meth1( x ); // <- hier wird's aufgerufen
Damit ist die 'formale' Schnittstelle zwischen langFunc und CMyClass relativ breit. Der Aufrufer weiß gar nicht so recht, was da innerhalb von langFunc mit 'a' passiert.
Nun gibt es die Möglichkeit, diesen Zugriff mittels eines Funktors (Foo s.u.) zu beschränken. Ausgeschrieben kann das so aussehen.struct Foo { explicit Foo( CMyClass& a ) : m_a( a ) {} void operator()( int x ) { m_a.Meth1( x ); } private: CMyClass& m_a; }; // der Aufruf von langFunc passiert jetzt mit CMyClass a; langFunc( Foo( a ), ... ); // dem Foo-Objekt wird eine Referenz von a mitgegeben // und innerhalb des (jetzt als Template codierten) langFunc geschieht template< typename T > void langFunc( T f, ..Rest interesiert hier nicht ) { // bla bla f( x ); // <- hier wird a.Meth1( x ) aufgerufen
Und damit man das alles (struct Foo s.o.) nicht selbst hinschreiben muss, kann man sich das von boost::bind generieren lassen. Der Ausdruck
boost::bind( &CMyClass:.Meth1, &a, _1 ); // _1 steht als Platzhalter für den Parameter
generiert genau so ein Funktor-Objekt wie Foo mit der Signatur void(*)( int ); dieser Funktor wird in langFunc aufgerufen und damit indirekt wieder die Methode Meth1 des Objekts 'a'. Der ganze Aufwand dient wie gesagt dazu, die Schnittstelle zu reduzieren und damit z.B. ganz konkret auch die Möglichkeit zu haben, von einem Objekt einer ganz anderen Klasse eine ganz andere Methode innerhalb von langFunc aufzurufen, und das ohne an langFunc eine Zeile zu ändern.
.. Verwirrung perfekt
?
Werner
-
Hmm gut, was nun - nur reine Geschmacksache?
Ich verstehe das jetz so: Uebergibt man bei pass-by-reference nur eine Reference, sollte man diese als Funktionsparameter auch mit const deklarieren und hat dann eben auch die dementsprechenden Eigenschaften. Stoeren diese "const-Eigenschaften", sollte man stattdessen die Adresse uebergeben, muss aber eine etwaige Behandlung fuer null implementieren. Hab ich das richtig verstanden?
Dann stellt sich fuer mich die Frage, ob es eben nicht auch Situationen/Faelle gibt, in denen eine Uebergabe MIT einer Reference OHNE const sinnvoll ist?
returnTyp function( paramTyp ¶m)
statt
returnTyp function( const paramTyp ¶m)
-
[quote="Corcovado"]Hmm gut, was nun - nur reine Geschmacksache?[quote]
jo.
das problem ist, daß wegen der gut funktionierenden RVO es kaum noch fälle gibt, wo man nicht-const-referenzen oder zeiger als funktionsparameter benötigen würde. so richtig wenige fälle. eigentlich so wenige fälle, daß es egal ist.mir fällt folgender ein:
template<typename T> class Lock{ NOCOPY; private: T& object; public: Lock(T& o): object(o){ o.lock(); } ~Lock(){ o.unlock(); } };
hier fühlt sich ne referenz irgendwie gescheiter an.
würde ich einen vector füllen wollen und nicht auf RVO hoffen können, würde ich wohl einen zeiger nehmen.
und nicht zu vergessen den lokale-referenz-trick:
void collectThingies(vector<int>* result){ assert(result!=0); vector<int>& r=*result; for(int i=0;i<100;++i) r.push_back(i*i%101); sort(r.begin(),r.end()); }
aber es kommt zu selten vor, ich habe keine meinung mehr zu diesem punkt.