PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : etwas in der Art von lamda functions (?) in C++


mekakic
2011-08-04, 14:34:37
Ich hab gerade ein kleines Problem und kein C++0x ... bin da noch nicht sicher aber nach der Beschreibung hört sich das auf Anhieb etwas nach den Lamda functions in C++0x an.

Denn zur Anbindung an ein remote Interface habe ich einen Block Standardcode: eine Mischung aus Loggings, Loops und try/catch Blöcken mit Behandlung für einen großen Satz von Standard-Exceptions gefolgt von ein paar User Exceptions. In diesem try-Block ist häufig nur der eigentliche Interface Call anders und der Code drum rum zur Absicherung oft identisch.

some_interface_impl::foo()
{
//logging
//some flow control
while(success)
{
try
{
remote_interface_p->foocall_q(parameter_r, parameter t, ... );
}
catch( EXCEPTION_A )
{
/* do this */
}
catch( EXCEPTION_Z )
{
/* do that */
}
/**/
catch( CUSTOM_EXCEPTION_A )
{
/* do that */
}
/**/
catch( CUSTOM_EXCEPTION_B )
{
/* do that */
}
/* more flow control */
}
}


Gibt es unter C++ eine elegante Methode das zu kapseln anstatt sich für >20 Funktionen einen copy/paste-Orgie zu veranstalten? Ich habe fast 200 Zeilen, die dann immer wieder kopiert werden, um einen call auf ein remote Interface zu kapseln. Irgendwie würde ich gerne den Funktions call da rausziehen und diese ganze Funktionalität generisch mit einem Call machen, der dann nur noch den Interface Parameter als Aufruf bekommt.

Das zweite Problem, dann noch richtig zu reagieren, wenn das Interface User Exceptions hat, auf die dann reagiert werden muß. Geht das mit C++ brauchbar?

Tiamat
2011-08-04, 14:56:22
Du könntest Funktionszeiger benutzen und die in ner Collection speichern.

Gast
2011-08-04, 20:24:36
Zur Modellierungszeit: austauschbaren Code per virtual Function abstrahieren
Zur Programmierzeit: Ctrl-C, Ctrl-V
Vorm Kompilieren: Makro (beispielsweise catch Blöcke in ein Makro verfrachten)
Beim Kompilieren: Template (da hast du deine funktionale Programmierung)
Zur Laufzeit: Funktionspointer (wenns so dynamisch ist, dass virtual Functions nicht ausreichen)

Such dir was aus.

Coda
2011-08-13, 13:54:36
Ich hab's zwar nicht ganz verstanden, aber das schreit doch nach einem Template.

Ectoplasma
2011-08-14, 01:27:20
Dein Problem ist nicht wirklich klar. Wer ruft hier was auf? Wo kommen die unterschiedlichen Parameter her? Gibt es keine höhere abstraktere Ebenen, auf der man die Exceptions abfangen kann? Mit templates geht das nicht wirklich, weil die Signature von foocall_q immer anders zu sein scheint.

Ich würde sagen, dass dein Problem eher was mit aspektorientierter Programmierung zu tun hat, nur leider bietet das C++ nicht.

An deiner Stelle würde ich versuchen, das Problem auf einen Nenner zu bringen und nur dort loggen und Excpetions catchen.

Marscel
2011-08-14, 03:22:26
Dein Problem ist nicht wirklich klar.

Ich vermute einfach, er möchte das Objekt proxyen - und jeder Aufruf hat halt diesen Overhead.

So ne Idee:

class RemoteCaller {
protected:
RemoteInterface* remote_object;
public:
RemoteCaller(RemoteInterface* i) : remote_object(i) {};
virtual void remote_call() = 0;
// ...
};

class FooRemoteCaller : public RemoteCaller {
private:
/* Call-Parameter */
public:
FooRemoteCaller(/* Call-Parameter */, Interface* i) : /*...,*/ RemoteCaller::RemoteCaller(i) {};
void remote_call() {
remote_object->remote_foo(/* Call-Parameter */);
}
// ...
};

Und in deine alte Proxy-Klasse wird dann sowas:
class some_interface_impl {
public:
void foo();
void bar();
private:
void interface_call(RemoteCaller&);
// ... remote_interface_p und so
};

void some_interface_impl::foo() {
FooRemoteCaller caller(/* gedöns */, remote_interface_p);
interface_call(caller);
}

void some_interface_impl::bar() {
BarRemoteCaller caller(/* gedöns */, remote_interface_p);
interface_call(caller);
}

void some_interface_impl::interface_call(RemoteCaller& caller) {
// Logging, whatever
try {
caller.remote_call();
}
catch (...) {
}
}


Ist aus der Hand geschrieben, können also einige Fehler drin sein - geht hier aber eher um die Idee.

GMP
2011-08-26, 10:54:07
vielleicht hilft dir boost lambda (http://www.boost.org/doc/libs/1_47_0/doc/html/lambda.html) oder irgendwas anderes aus deren sammlung?