I have a cheesesales.txt
CSV file with all of my recent cheese sales. I want to create a class CheeseSales
that can do things like these:
CheeseSales sales("cheesesales.txt"); //has no default constructor
cout << sales.totalSales() << endl;
sales.outputPieChart("piechart.pdf");
The above code assumes that no failures will happen. In reality, failures will take place. In this case, two kinds of failures could occur:
My question is simply: How would you design this code to handle failures?
One idea: Return a bool
from the regular method indicating failure. Not sure how to deal with the constructor.
How would seasoned C++ coders do these kinds of things?
The best way to signal constructor failure is therefore to throw an exception. If you don't have the option of using exceptions, the "least bad" work-around is to put the object into a "zombie" state by setting an internal status bit so the object acts sort of like it's dead even though it is technically still alive.
We use constructors to initialize the object with the default or initial state. The default values for primitives may not be what are you looking for. Another reason to use constructor is that it informs about dependencies.
Constructor is used to create and initialize an Object . Method is used to execute certain statements. A constructor is invoked implicitly by the System. A method is to be invoked during program code.
When throwing an exception in a constructor, the memory for the object itself has already been allocated by the time the constructor is called. So, the compiler will automatically deallocate the memory occupied by the object after the exception is thrown.
In C++ exceptions is the way to report errors. BTW exception in initialization list CAN be handled.
A function-try-block associates a handler seq with the ctor-initializer, if present, and the function-body. An exception thrown during the execution of the initializer expressions in the ctor-initializer or during the execution of the function-body transfers control to a handler in a function-try-block in the same way as an exception thrown during the execution of a try-block transfers control to other handlers.
Good code usually should use minimum of try/catch blocks on most upper (thread) level. Ideally only one. This way, knowing that "everything throws", you have not think too much about errors and your normal scenario code flow looks clean.
A constructor is used for initializing object's internal state. Do not use it for making heavy operations like reading and processing files.
Use a method instead which will read the file and throw an exception (or return a boolean for success) incase an error occured. Catch this exception in your main flow and handle it as you see fit.
EDIT : If this is the whole class purpose than maybe ChessSales
should only contain the data and you should use a factory class (or maybe static utility class) which has a method for reading a CSV file and returning a ChessSales
object containing the relevant data read from the CSV file. This way you separate your data from the business logic (in this case reading and parsing the CSV file)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With