Recently I've been taking a hard look at my programming style and how to improve it. Let me begin by saying that in my current role, I'm the sole programmer. As a result, I can make things as hacky as I want, but I'm really striving to become a better, more sound programmer.
Also, my background was mainly C based, with essentially using C++ as a super-set of C when necessary. As a result, I have stumbled across the following conundrum.
I have always defined error codes with something like #define ERROR_FUNCTION_BLEW_UP -2 . In honesty, I can see the benefits of doing so since I don't have to allocate the memory to store -2. However, in C++ I can see the benefit of using a const variable since there's less chances of collisions between two competing macros.
As a result, I was wondering what the cleanest way is to implement error codes in C++. Namely, I'd like to have the client be able to check the return value of certain functions by doing something analogous to "if (return_value == ERROR_FUNCTION_BLEW_UP)". I've tried adding a const variable in each class, but then the code doesn't look right. That is, the client now checks something along the lines of "if (return_value == MyClass.kErrorFunctionBlewUp_)". Is there a cleaner way of accomplishing this, rather than having the constant be a public member of the class?
Also, to add onto my question, myClass is a base class, and now I want to add more error codes in MyDerivedClass. What's the best way of going about this and avoiding macros?
Thank you all for your help.
Use enums:
enum Errors
{
NO_ERROR = 0,
FUNCTION_BLEW_UP,
WTF_THIS_SHOULDNT_HAPPEN,
};
Also, consider using exceptions (look into std::exception) if they're more appropriate.
If you really want to just replace your macros, replace them with a constant. A constant has internal linkage (i.e. restricted to the translation unit ("file")) so the compiler can easily replace their use with just the constant inline and without using a single byte more or less than for a macro. Note that it is customary to keep ALL_UPPERCASE to macros, because macros don't follow normal code conventions, so you'd have to change that, too.
Then, in C++, you don't generally use returncodes that the caller has to check but exceptions which propagate automatically. If you want to keep the errorcodes, you can use an enumeration or constants and put them into a namespace. Note that enumerations leak into the surrounding namespace or class, which makes it preferable to wrap them up one level:
namespace errorcode
{
enum type
{
printer_on_fire,
volume_not_formatted,
bluescreen
};
}
Exceptions do sometimes contain error codes that further specify what failed though. Here's one way to specify them:
struct error:
std::runtime_error
{
...
enum code
{
printer_on_fire,
volume_not_formatted,
bluescreen
};
code fault;
};
Note that you don't have to nest the code, you can also build the exception type with the existing errorcode::type above. Some nesting is useful though, because enumerations otherwise pollute the surrounding namespace.
That said, you ask "do I place it at the top of the file before the class", but here you have a misconception. Firstly, not every file contains a class. Then, not every file that contains a class contains exactly one of them. For example, if the collection of errorcodes is used by a whole class hierarchy it makes sense to define it in a separate file to make clear that it doesn't belong to just one of them and that it can be used in related non-class functions, too. In that file, you would also stick e.g. a function to convert it to a string for debugging and maybe the exception type carrying one of them.
Related
I have a huge C++ solution created as a "win32 console application" project in MVS2008, the only Additional Options during the creation having been : "precompiled header".
In this solution I now have a huge amount of enums defined in various ways : they are always defined in a .h file, but they can be defined either within a namespace, either within a class, either within a class within a namespace.
I would like to define in more elegant way (I know how to do it in a bruteforce way, but it wouldn't be DRY, right ?) a function:
void myfunc( const char * )
Which would print all "stringed" values of an enum when I pass to it the "string value" of this enum.
To be precise, if I have somewhere in my code:
enum Place
{
Home,
Work
};
I would like to be able to pass to my function the string "Place", and my function to print the strings "Home" and "Work".
Having really A LOT of enums, I would like, if possible, to avoid modifying them a lot, ideally not at all. I thought of a small parser, but I don't think this optimal at all.
By the way, I am RESTRICTED not to use external things different from boost, but I can use macros. I would like to be able to somehow define the concepts of "loop" over enums, and of "loop within the "strings of enums"" as well, but don't see how to do it at all.
All ideas are welcome.
I'm starting to write some code using C++ and I have this simple class method from a simple task manager program I'm writing as an experiment:
void Task::setText(string text)
{
if(text.length() > MIN_LENGTH)
{
this->text = text;
}
}
As you can see, this method sets the class text attribute to the one passed to the method if it's length is higher than the MIN_LENGHT variable that is defined above the code I've shown. So I have to do something if the condition does not evaluate to true for the string passed to the method.
In the C++ book I bought, error handlings are not explained, instead it just uses assert everywhere. As assert just aborts the program if the expression is false, and this is intended as input validation, I looked for a better approach.
This search led me to C++ exceptions. There it explains how to create exceptions by creating a class that inherits from exception.
Good OOP practice says that every class should be independent from the others in the program. So where should I put this exception class I create? In the same header I define my Task class in? Or should it be in task.cpp where I define every method of the class?
Maybe this is a silly question but just want to be secure and follow a good software architecture practices from the beginning.
Recommendation #1: You need to read your book completely.
It is not true that in case of every error you should throw an exception. Exception should happen something less often that every 1000 calls to your function/method. 1000 is not a magic value here, in particular case other number might be appropriate.
In other words. The first question that you need to answer: how often this error may happen. If this may happen often, then the return value (bool or enum or int) is a better approach.
If you decided to use exception, it is better to derive it from std::exception. You should place exceptions of your project in a separate file. Think about a couple of classes, maybe 3-10. It is better to place a data field inside your exception class that should explain details of what happened instead of creating hundreds of different exception classes.
the exception class can be in a separate .h .cpp file. That way you can reuse for something else.
As my own rule of thumb:
assertions are for things that should never happen but we check just to be sure 100% sure
Exceptions is for error handling things that can happen when your program is in production
C++ standard library provides many exception class that you can use. For begining, you can use them. In your case, what applies seems to be range error.
If you still want to implement your own exception class, where you declare and implement it should depend on what they code for. If they code for a class specific error, you can put them in your class file. If you have to use them from multiple files, put them in they own .cpp/.hpp couple.
So I have this huge tree that is basically a big switch/case with string keys and different function calls on one common object depending on the key and one piece of metadata.
Every entry basically looks like this
} else if ( strcmp(key, "key_string") == 0) {
((class_name*)object)->do_something();
} else if ( ...
where do_something can have different invocations, so I can't just use function pointers. Also, some keys require object to be cast to a subclass.
Now, if I were to code this in a higher level language, I would use a dictionary of lambdas to simplify this.
It occurred to me that I could use macros to simplify this to something like
case_call("key_string", class_name, do_something());
case_call( /* ... */ )
where case_call would be a macro that would expand this code to the first code snippet.
However, I am very much on the fence whether that would be considered good style. I mean, it would reduce typing work and improve the DRYness of the code, but then it really seems to abuse the macro system somewhat.
Would you go down that road, or rather type out the whole thing? And what would be your reasoning for doing so?
Edit
Some clarification:
This code is used as a glue layer between a simplified scripting API which accesses several different aspects of a C++ API as simple key-value properties. The properties are implemented in different ways in C++ though: Some have getter/setter methods, some are set in a special struct. Scripting actions reference C++ objects casted to a common base class. However, some actions are only available on certain subclasses and have to be cast down.
Further down the road, I may change the actual C++ API, but for the moment, it has to be regarded as unchangeable. Also, this has to work on an embedded compiler, so boost or C++11 are (sadly) not available.
I would suggest you slightly reverse the roles. You are saying that the object is already some class that knows how to handle a certain situation, so add a virtual void handle(const char * key) in your base class and let the object check in the implementation if it applies to it and do whatever is necessary.
This would not only eliminate the long if-else-if chain, but would also be more type safe and would give you more flexibility in handling those events.
That seems to me an appropriate use of macros. They are, after all, made for eliding syntactic repetition. However, when you have syntactic repetition, it’s not always the fault of the language—there are probably better design choices out there that would let you avoid this decision altogether.
The general wisdom is to use a table mapping keys to actions:
std::map<std::string, void(Class::*)()> table;
Then look up and invoke the action in one go:
object->*table[key]();
Or use find to check for failure:
const auto i = table.find(key);
if (i != table.end())
object->*(i->second)();
else
throw std::runtime_error(...);
But if as you say there is no common signature for the functions (i.e., you can’t use member function pointers) then what you actually should do depends on the particulars of your project, which I don’t know. It might be that a macro is the only way to elide the repetition you’re seeing, or it might be that there’s a better way of going about it.
Ask yourself: why do my functions take different arguments? Why am I using casts? If you’re dispatching on the type of an object, chances are you need to introduce a common interface.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Static members class vs. normal c-like interface
I am looking at somebodies code and there are several dozen constants defined in a class like this:
// header file
class Defines
{
public:
static const int Val1;
static const int ValN;
static const char* String1;
static const char* StringN;
...
}
// .CPP
const char* Defines::String1 = "some value"
etc.
Is there some reason to do things this was as opposed to using a namespace instead?
Are there advantages/disadvantages of one over the other
--------- Edit ----------
I'm sorry, I obviously should have pointed this out explicitly, as nobody has inferred it from the name of the class - which is "Defines". i.e. these constants are not associated with a particular class, there has been a class created specifically just to hold constants and nothing else, that is all the class Defines contains.
My question is not why should you place constants in a particular class, the question is is there any value in collecting dozens of them together and placing them in a class whose only purpose is to collect together constants, as opposed to collecting them together in a namespace, or just collecting them together in a header file specifically for that purpose etc.
(There is no currently existing namespace in the project therefore potential issues of polluting the namespace as mentioned in answers are not relevant in this case.)
----- 32nd edit -----------
and a follow up question ---
is placing
const char* Defines::StringN = "Somevalue"
in the .h file inefficient versus placing it in the .cpp file?
Because those constants may be tightly coupled to that class. IE Maybe members of the class take those constants as arguments or return them. Maybe the only place they are meaningful is in the interface to this class, so putting them in a separate namespace doesn't make sense because they only matter to that class.
There is no reason to do it the way it is done here; just like there is not really a reason to use class Defines { public: ... }; instead of struct Defines { ... };. Perhaps whoever wrote the code had previously been writing in a language that does not support namespaces/global variables in namespaces, or thought that this looked `neater' than a lot of extern statements and a namespace.
There is some practical use for this, however, if you intend to make some of these constants private, and then give access to only a few functions/classes. From the looks of it, however, this isn't the case, and it would make sense to change this to be a namespace -- that way, one could use using Defines::constant; and similar.
Response to first edit: The global namespace is also a namespace, and it is more dangerous to pollute than other namespaces, as things are more likely to leak into it. In that sense, it is better to put the variables in a class, but still not as good as putting them in a namespace of their own.
Response to second edit: const char* Defines::StringN = "Somevalue"; in a header would lead to the constant being defined multiple times, and the program would fail to link. However, if you prepend an extern to that, and put the definition in a .cpp file, everything will be fine, and there should be no performance penalty.
For a few reasons:
You're not cluttering your namespace with potentially random constants.
You're adding meaning to both the class and the constants themselves by including them with their associated class.
If I were to define a global/namespace constant named NAME, then what is it associated with? If I added into the class itself, then you're forced to reference is with the class name, which adds meaning to the usage and makes the code more readable and less error prone.
Of course, this can be abused. You can misplace constants. You can improperly put truly global constants in specific classes. You can, in both cases, give bad names.
In general, there's no reason to use a type this way. I have seen it argued that if the "collection of constants" evolves into a concrete object, starting this way makes the transition easier. In practice, I've never seen this happen. It just hides intent, and potentially flutters the code with private constructors.
One could argue that classes work with templates, while namespaces do not. So something like the following would only work if Defines is a class:
template<typename T> int function() {
return T::x + T::y;
}
//later
cout << function<Defines>() << function<OtherDefines>() << endl;
In most cases, there's probably a redesign that would work better, particularly if all you have are "constants" that aren't really. Occasionally, this may come in handy, though.
At times, it can also fight argument dependent lookup. In brief, the compiler is allowed to expand it's search for eligable function names to different name namespaces based on the parameters passed to the function. This does not extend to static functions of a class. This applies more to the general case, though, where the "static class" also includes nested types and functions in addition to the collection of constants.
Why people do this varies. Some come from languages where can't be used this way, others just don't know any better.
For most things, it makes sense to give them the smallest scope possible. In this case its not so much an issue of visibility, but in clarity.
If you see String1 in a method, you have no idea where it came from. If you see Defines::String1, you can say "OK, this is a variable from the class Defines, let me go there and see what it is and what it's supposed to be". Looking in one class is a lot better than looking through an entire namespace that might even be spread across multiple source files. Obviously if the variable is in a class because its used primarily in that class, there's no doubt whatsoever that's that's where it should be. :D
Are (seemingly) shady things ever acceptable for practical reasons?
First, a bit of background on my code. I'm writing the graphics module of my 2D game. My module contains more than two classes, but I'll only mention two in here: Font and GraphicsRenderer.
Font provides an interface through which to load (and release) files and nothing much more. In my Font header I don't want any implementation details to leak, and that includes the data types of the third-party library I'm using. The way I prevent the third-party lib from being visible in the header is through an incomplete type (I understand this is standard practice):
class Font
{
private:
struct FontData;
boost::shared_ptr<FontData> data_;
};
GraphicsRenderer is the (read: singleton) device that initializes and finalizes the third-party graphics library and also is used to render graphical objects (such as Fonts, Images, etc). The reason it's a singleton is because, as I've said, the class initializes the third-party library automatically; it does this when the singleton object is created and exits the library when the singleton is destroyed.
Anyway, in order for GR to be able to render Font it must obviously have access to its FontData object. One option would be to have a public getter, but that would expose the implementation of Font (no other class other than Font and GR should care about FontData). Instead I considered it's better to make GR a friend of Font.
Note: Until now I've done two things that some may consider shady (singleton and friend), but these are not the things I want to ask you about. Nevertheless, if you think my rationale for making GR a singleton and a friend of Font is wrong please do criticize me and maybe offer better solutions.
The shady thing. So GR has access to Font::data_ though friendship, but how does it know exactly what a FontData is (since it's not defined in the header, it's an incomplete type)? I'll just show the code and the comment that includes the rationale...
// =============================================================================
// graphics/font.cpp
// -----------------------------------------------------------------------------
struct Font::FontData
: public sf::Font
{
// Just a synonym of sf::Font
};
// A redefinition of FontData exists in GraphicsRenderer::printText(),
// which will have to be modified as well if this definition is modified.
// (The redefinition is called FontDataSurogate.)
// Why not have FontData defined only once in a separate header:
// If the definition of FontData changes, most likely printText() text will
// have to be altered also regardless. Considering that and also that FontData
// has (and should have) a very simple definition, a separate header was
// considered too much of an overhead and of little practical advantage.
// =============================================================================
// graphics/graphics_renderer.cpp
// -----------------------------------------------------------------------------
void GraphicsRenderer::printText(const Font& fnt /* ... */)
{
struct FontDataSurogate
: public sf::Font {
};
FontDataSurogate* suro = (FontDataSurogate*)fnt.data_.get();
sf::Font& font = (sf::Font)(*suro);
// ...
}
So that's the shady thing I'm trying to do. Basically what I want is a review of my rationale, so please tell me if you think I've done something horrendous or if not confirm my rationale so I can be a bit surer I'm doing the right thing. :) (This is my biggest project yet and I'm only at the beginning so I'm kinda feeling things in the dark atm.)
In general, if something looks sketchy, I've found that it's often worth going back a few times and trying to figure out exactly why that's necessary. In most cases, some kind of fix pops up (maybe not as "nice", but not relying on any kind of trick).
Now, the first issue I see in your example is this bit of code:
struct FontDataSurogate
: public sf::Font {
};
occurs twice, in different files (neither being a header). That may come back and be a bother when you change one but not the other in the future, and making sure both are identical will very likely be a pain.
To solve that, I would suggest putting the definition to FontDataSurogate and the appropriate includes (whatever library/header defines sf::Font) in a separate header. From the two files that need to use FontDataSurogate, include that definition header (not from any other code files or headers, just those two).
If you have a main class declaration header for your library, place the forward declaration for the class there, and use pointers in your objects and parameters (regular pointers or shared pointers).
You can then use friend or add a get method to retrieve the data, but by moving the class definition to its own header, you've created a single copy of that code and have a single object/file that's interfacing with the other library.
Edit:
You commented on the question while I was writing this, so I'll add on a reply to your comment.
"Too much overhead" - more to document, one more thing to include, the complexity of the code grows, etc.
Not so. You will have one copy of the code, compared to the two that must remain identical now. The code exists either way, so it needs documented, but your complexity and particularly maintenance is simplified. You do gain two #include statements, but is that such a high cost?
"Little practical advantage" - printText() would have to be modified every time FontData is modified regardless of whether or not it's defined in a separate header or not.
The advantage is less duplicate code, making it easier to maintain for you (and others). Modifying the function when the input data changes is not surprising or unusual really. Moving it to another header doesn't cost you anything but the mentioned includes.
friend is fine, and encouraged. See C++ FAQ Lite's rationale for more info: Do friends violate encapsulation?
This line is indeed horrendous, as it invokes undefined behavior: FontDataSurogate* suro = (FontDataSurogate*)fnt.data_.get();
You forward declare the existence of the FontData struct, and then go on to fully declare it in two locations: Font, and GraphicsRenderer. Ew. Now you have to manually keep these exactly binary compatible.
I'm sure it works, but you're right, it is kindof shady. But whenever we say such-and-such is eeevil, we mean to avoid a certain practice, with the caveat that sometimes it can be useful. That being said, I don't think this is one of those times.
One technique is to invert your handling. Instead of putting all of the logic inside GraphicsRenderer, put some of it inside Font. Like so:
class Font
{
public:
void do_something_with_fontdata(GraphicsRenderer& gr);
private:
struct FontData;
boost::shared_ptr<FontData> data_;
};
void GraphicsRenderer::printText(const Font& fnt /* ... */)
{
fnt.do_something_with_fontdata(*this);
}
This way, the Font details are kept within the Font class, and even GraphicsRenderer doesn't need to know the specifics of the implementation. This solves the friend issue too (although I don't think friend is all that bad to use).
Depending on how your code is laid out, and what it's doing, attempting to invert it like this may be quite difficult. If that is the case, simply move the real declaration of FontData to its own header file, and use it in both Font and GraphicsRenderer.
You've spent a lot more effort asking this question then you've supposedly saved by duplicating that code.
You state three reasons you didn't want to add the file:
Extra include
Extra Documentation
Extra Complexity
But I would have to say that 2 and 3 are increased by duplicating that code. Now you document what its doing in the original place and what the fried monkey its doing defined again in another random place in the code base. And duplicating code can only increase the complexity of a project.
The only thing you are saving is an include file. But files are cheap. You should not be afraid of creating them. There is almost zero cost (or at least there should be) to add a new header file.
The advantages of doing this properly:
The compiler doesn't have to make the definition you give compatible
Someday, somebody is going to modify the FontData class without modifying PrintText(), maybe they should modify PrintText(), but they either haven't done it yet or don't know that they need to. Or perhaps in a way that simply hasn't occoured to additional data on FontData make sense. Regardless, the different pieces of code will operate on different assumptions and will explode in a very hard to trace bug.