[C++] Funktionen vom Typ "bool" direkt aufrufen. - O.K. oder unschön?

SvenK

Grünschnabel
Wir müssen in unserem C++ Kurs eine Klasse "CIntelligentCoffeeMachine" schreiben und haben den groben Klassenaufbau vorgegeben (einige Methoden und Attribute).

Dort haben wir einige Methoden vom Typ "bool" welche ich persönlich aber als "void" deklarieren würde, z.B. "bool OpenLid()". Wenn ich diese in meiner Testklasse direkt aufrufe (als wäre sie vom Typ void) erhalte ich vom compiler nichtmal eine Warnung (Entwicklungsumgebung ist g++ in Kombination mit Eclipse und Rhapsody). Heißt das also das ist so in Ordnung wenn ich auf den Rückgabewert überhaupt nicht eingehe? Oder ist das unschöne Programmierung und ich sollte das ganze in eine if-Abfrage packen [ if( !LidOpen() ) std::cout << "Error occured." << std::endl; ] ?
Da das ganze bewertet wird würde ich das ungerne "schlecht" machen.

Besten Dank im vorraus,

Sven.
 
Also irgendwie hast du dir ja die Antwort schon selber gegeben.
Denk' mal so: Was wäre dir als Benutzer lieber?
Diese Kaffeekiste streikt einfach und macht nichts weiter?
Oder sie meldet entsprechende Fehler?

Also bevor mir so ein Kaffeeautomat brühendes Wasser auf die Pfoten gießt, weil ein Programmierer zu faul war, den Rückgabewert von OpenLid() abzufragen, programmiere ich doch selber besser und warne vor Starten des Brühvorgangs, daß der "Lid" noch offen ist (OpenLid == true) und verweigere das Brühen des Wassers.

Ergo:
Nimm die lange Variante mit Abfrage des Rückgabewerts, denn der hat schon seinen Sinn.
Nur weil du alle Rückgabewerte mittels void einfach ignorieren kannst, heißt noch lange nicht, daß du sie ignorieren solltest. ;)
 
Vom Prinzip her hast du natürlich vollkommen recht. Nur werden innerhalb der Methoden noch Attribute als Flags gesetzt. D.h. ich bin in den weiteren Methoden (z.B. InsertCoffee() ) gar nicht auf die Rückgabewerte angewiesen, da ich eben diese Attribute abfrage (z.B. m_bLidOpen:bool ). Um den Benutzer zu informieren gebe ich innerhalb der einzelnen Methoden natürlich Statusmeldungen aus. D.h. bei einem fehlschlagen des Deckel öffnens würde ich quasi zwei Meldungen erhalten:
PHP:
bool CIntelligentCoffeeMachine::CloseLid() {
    //#[ operation CloseLid() 
    if(m_bLidOpen == false)
    {
    	std::cout << "Lid already closed." << std::endl;
    	return false;
    }
    else
    {
    	m_bLidOpen = false;	
    	std::cout << "Closed lid." << std::endl;
    	return true;
    }
    //#]
}
rufe ich dann in der Testklasse als
PHP:
if(!m_MyIntelligentCoffeeMachine.OpenLid())
    	std::cout << "An error occured." << std::endl;
auf und würde mir im Falle eines fehlschlagens
Code:
Lid already closed.
An error occured.
ausgeben. Also eine doppelte Fehlermeldung.
 
Aaah, jetzt kapiere ich das. Doppelte Statusmeldung sozusagen. Hmmm... Benutze ich auch manchmal. Da sehe ich aber dennoch einen Vorteil und zwar ganz für dich persönlich. ;)

Über die Membervariablen kannst du ganz allegmein den Zustand der einzelnen Attribute der Maschine abfragen (also z.B. über m_bLidOpen). Aber über das Auswerten der Rückgabewerte kannst du dir selber schöne Breakpoints für's Debuggen setzen, im Sinne von
Code:
if DoLidOpen() == false
  ShowMessage("Fehler in Modul schießmichtot Zeile wasweissich");
So kannst du später im Fehlerfalle genauer nachvollziehen, was gegen die Wand gefahren ist, ohne daß du dich mit einem Einzelschrittdebugger erstmal bis zur Fehlerzeile durchecheln musst.

Aber prinzipiell kann ich dir dann schon Recht geben:
Für die reine Funktionalität des Programms lassen sich dann auch voids als Rückgabeparameter verwenden, wenn die Zustände der Attribute in entsprechenden Membervariablen abgelegt werden. Ist nur ein wenig schlampig und ich persönlich würde es nicht machen, weil ich dazu einfach zu oft erlebt habe, was für Auswüchse so eine Schludrigkeit sehr, sehr schnell annehmen kann. "Wehret den Anfängen" und so. ;)
 
Vom Prinzip her hast du natürlich vollkommen recht. Nur werden innerhalb der Methoden noch Attribute als Flags gesetzt. D.h. ich bin in den weiteren Methoden (z.B. InsertCoffee() ) gar nicht auf die Rückgabewerte angewiesen, da ich eben diese Attribute abfrage (z.B. m_bLidOpen:bool ). Um den Benutzer zu informieren gebe ich innerhalb der einzelnen Methoden natürlich Statusmeldungen aus. D.h. bei einem fehlschlagen des Deckel öffnens würde ich quasi zwei Meldungen erhalten:
PHP:
bool CIntelligentCoffeeMachine::CloseLid() {
    //#[ operation CloseLid() 
    if(m_bLidOpen == false)
    {
    	std::cout << "Lid already closed." << std::endl;
    	return false;
    }
    else
    {
    	m_bLidOpen = false;	
    	std::cout << "Closed lid." << std::endl;
    	return true;
    }
    //#]
}
rufe ich dann in der Testklasse als
PHP:
if(!m_MyIntelligentCoffeeMachine.OpenLid())
    	std::cout << "An error occured." << std::endl;
auf und würde mir im Falle eines fehlschlagens
Code:
Lid already closed.
An error occured.
ausgeben. Also eine doppelte Fehlermeldung.
Das ist allerdings meiner Meinung etwas ungünstig. Der Rückgabewert sollte angeben ob die Operation erfolgreich war oder nicht. Wenn ich die Operation closeLid aufrufe und die Lade ist bereits zu, dann war die Operation doch erfolgreich, oder nicht?! Wenn allerdings irgendwas die Lade blockiert und die Lade kann nicht geschlossen werden, dann sollte falsch zurückgegeben werden.

Es ist halt die Frage ob du wirklich diese Statusmeldungen in den Low-Level Methoden einfügen willst. Diese Funktionen sollten eigentlich mit relativ wenig Interaktion funktionieren. So kann man nachher unabhängig diese Klassen benutzen (z.B. auch in GUI Programmen die normalerweise keine Standardausgabe benutzen) ohne störende Statusmeldungen zu bekommen.

Gruß
 
Zurück