Consider the following class:
class A
{
A();
int number;
void setNumber(int number);
};
You could implement 'setNumber' in 3 ways:
Method 1: Use the 'this' pointer.
void A::setNumber(int number)
{
this->number = number;
}
Method 2: Use the scope resolution operator.
void A::setNumber(int number)
{
A::number = number;
}
Method 3: Instead, denote all member variables with 'm' or '_' (this is my preferred method).
void A::setNumber(int number)
{
mNumber = number;
}
Is this just personal preference, or is there a benefit to choosing a particular method?
This is mostly a personal preference, but let me share my perspective on the issue from inside a company where many small games are being made simultaneously (and so there are many coding styles being used around me).
This link has several good, related, answers: Why use prefixes on member variables in C++ classes
Your option 1:
void A::setNumber(int number)
{
this->number = number;
}
First off, many programmers tend to find this cumbersome, to continually type out the ' this-> '. Second, and more importantly, if any of your variables shares a name with a parameter or a local variable, a find-replace designed to say, change the name of 'number' might affect the member variables located in the find-replace scope as well.
Your option 2:
void A::setNumber(int number)
{
A::number = number;
}
The problem I've run into with this, is that in large classes, or classes with large functions (where you cannot see the function or the class is named unexpectedly), the formatting of A::(thing) looks very much like accessing a part of a namespace, and so can be misleading. The other issue is the same as #2 from the previous option, if your names are similar to any variables you're using there can be unexpected confusion sometimes.
Your option 3:
void A::setNumber(int number)
{
mNumber = number;
}
This is the best of those three presented options. By creating (and holding to!) a syntax that involves a clear and meaningful prefix, you not only create a unique name that a local (or global) variable won't share, but you make it immediately clear where that variable is declared, regardless of the context you find it in. I've seen it done both like this ' mVariable ' and like this 'm_variable' and it mostly depends upon if you prefer underscores to uppercase concatenation. In addition, if your style tends to add things like ' p 's on for pointers, or ' g 's on for globals, this style will mesh well and be expected by readers.
It is a matter of style, thus personal preference, or a preference of the team you are working with or the boss of the team you are working with.
Option 4:
void A::setNumber(int n)
{
number = n;
}
Why is the benefit of using the same name for a member and a parameter. No good can come of this. Sure, it's clear now, but when your methods get large, and the prototype doesn't fit in the screen anymore, and there's some other developer writing code, he may forget to qualify the member.
its all personal preference
but here is a good discussion on it at a high non language level
https://stackoverflow.com/questions/381098/what-naming-convention-do-you-use-for-member-variables
I would say the choice between Method 1 and Method 3 is a matter of personal or organizational style.
Method 2 is an inferior because Class::member typically denotes a static member variable, and thus would cause confusion if used to disambiguate between a parameter and member variable.
I am going to agree with Luchian by providing a better variant. The other examples you provide are too cumbersome or confusing.
Option 4:
void A::setNumber(int aNumber)
{
theNumber = aNumber;
}
This is part of the coding standard we use at my employer and it is very clear what you are describing. It is not Hungarian notation.
Related
My noble quest is to get rid of singletons and static classes.
Background:
I have the following structures:
CmdFrequently instantiated object, it holds a name of the command (string), and functor to the static method of any class as a pointer.It is typically created in main classes such as Input, Console, Render, etc. and refers to methods within the class that it is created in, giving a runtime verbal interface to those methods.Cmds also interpret parameters in a form of a string array, where first argument is the name of the Cmd, and all consecutive strings are direct arguments for the static method being invoked. The argument count and argument array are stored in Commander, and changed before each Cmd call.
CommanderCommander is used to interpret string commands (which may come directly, or through Console) and it executes the Cmd which was stored in the buffer as a string (by invoking it's functor).
Problem:
Problem is that I am attempting to get rid of all the static classes (which I now turned into singletons for testing), and I am making the system fully modular and loosely coupled. This in turn prevents me from having static calls which Cmds could point to.
First instinct was to change the functor from a typedef into a template class, which would store an object and method, but it looks very messy and complex, and I personally am not comfortable going from:
Cmd::create("toggleconsole", Console::toggle);
To:
Cmd::create("toggleconsole", new FunctorObject<Console>(&Console::get(), &Console::toggle));
The final Cmd creation looks very obscure and misleading as to who is in charge of the Functor deallocation.
I am also in the process of moving Cmd creation from a static method call, into the Commander class, so it would look like commander.createCmd("command_name", ...); instead of Cmd::create("command_name",...); This is because Commander is no longer going to be static (or singleton), so all commands which it handles must belong to it.
I am, however, at a complete loss as to what my options/alternatives are to register Cmds, and maintain the loose coupling by allowing string commands to be issued to the Commander.
I have considered making each of the main classes derive from a CmdListener class, which would register the object with the Commander upon creation, and then during execution pass a command to all registered objects which overwrote the "onCmd(const Cmd &command)".
This leaves some unanswered questions as well: how will Cmd relay which method of class should be invoked? Keeping pointers wouldn't make sense and would be subject to high level of obscurity (as demonstrated above). Also, I wish to not reinterpret strings in onCmd method for every class that may handle that cmd.
It is a lot of information, but does anybody have any ideas on how to deal with this issue?
Also, all my classes must be aware of Commander and Console objects, which are no longer singleton/static. So far, I have placed them inside a Context object, and am passing it around like a little capsule. Any ideas on how to solve these post-singleton residual problems?
This project is my personal work, and I am planning to use it on my resume - hence, I do not want my potential employers to see any singletons (nor do I want to explain myself as to why, since I can prove to myself they are not truly necessary).
Thanks a ton!
edit: typography.
This is a job for the function class. You can find one in Boost, or in TR1 or C++0x. It looks like std::function<void()>, for example. This is often partnered with bind, which you will need if you want to refer to functional objects in a generic way, rather than take them by value, and is also found in Boost, TR1 or C++0x. If you have lambda functions, you can use them too, which is an excellent method.
class Commander {
std::map<std::string, std::function<void()>> commands;
public:
void RegisterCommand(std::string name, std::function<void()> cmd) {
commands[name] = cmd;
}
void CallCommand(std::string name) {
commands[name]();
}
};
void sampleFunc() {
std::cout << "sampleFunc()" << std::endl;
}
struct sampleStruct {
int i;
void operator()() {
std::cout << i;
std::cout << "sampleStruct()() and the value of i is " << i << std::endl;
}
};
int main() {
Commander c;
c.RegisterCommand("sampleFunc", sampleFunc);
sampleStruct instance;
instance.i = 5;
c.RegisterCommand("sampleStruct", instance);
std::string command;
while(std::cin >> command && command != "exit") {
c.CallCommand(command);
}
std::cin.get();
}
in Java code convention is simple and obvious, in this style:
public:
int GetMyAge(){
return myAge;
}
void SetMyAge(int myAge){
this->myAge = myAge;
}
private:
int myAge;
(I know it's "again the same thing", but) I have read most of related questions on SO and I still don't know "the best one" and "the most official" way to do it in C++. It can't be just a matter of preferences, can it?
EDIT:
Seems like it can.
Best not to do it at all. Can your age actually be changed like that? Blindly providing getters and setters for all properties is a sign you have not designed your class properly.
The best style is the one that allows you and your team to make quality software that your clients continue to pay you for.
How does this style work for you and your team? Do you find it causes (or prevents) bugs? Do you find it easy to maintain the code? Do you bicker about the formatting?
Answer those questions and the answer to your question will arise out of them.
A simple answer: class names are capital in general in c++ (except for the std classes), methods are lower case, some frameworks like Qt prefer camelCase, however I prefer underscore_notation -- and so do the STL see eg. "auto_ptr".
Classes do not always have separate .h files, because here a .java file is split up into a .h header (for an entire package), and .cpp implementation files, one per class.
class TipicalCamelCase {
public:
/// mark the frequently used small functions inline in the class def.
inline int getMyAge() const;
void setMyAge(int myAge=5); // defaults go to the definition.
/// for efficiently setting more complex things.
void setMyStuff(const MyStuff& myStuff);
/// a tipical class-valued getter
/// (sometimes scoffed at since it can have memory leaks
/// if you dismiss the class but still use and don't copy MyStuff.)
const MyStuff& getMyStuff() const;
/// a safe getter, but forces copying-out MyStuff.
MyStuff getMyStuff() const;
private:
int myAge;
static const int zero=0; // allowed only in the new C++11 standard.
static const int one;
};
Some implementations/initializations (usually in separate TipicalCamelCase.cpp file):
const int TipicalCamelCase::one = 1;
int TipicalCamelCase::getMyAge() const{
return myAge;
}
void TipicalCamelCase::setMyAge(int myAge_){
myAge = myAge_;
}
Underscore style is the same but
int Tipical_camel_case::get_my_age() const
{
return my_age;
}
I prefer this as it looks cleaner both in the header and in the implementation files.
You can see that function headlines are lengthier than in java. Especially you'll see with templates (generics) 2 lines' header is typical, so it is worth to put them a bit more separated.
template<typename _Tp>
int Class_name::general_function(_Tp);
I think it should do as a style intro.
If you use inheritance, for the java-style working, mark every function except the constructors virtual so that the #overrides behave correctly.
What you have written in the above code is a correct syntax . If you are looking for a thumb rule, code your acccessor functions in such a way that they are set / get exactly the values .
EG :
void SetMyAge(int newAge)
{
if(newAge > 10 && newAge < 100)
_age = newAge ;
}
I would prefer to put the validation "newAge > 10 && newAge < 100" in a different function, IsValidAge ; even if the code is just one line. On the long run, small functions help in maintaining the code, and helps new developers to understand the code better.
void SetMyAge(int newAge)
{
if(IsValidAge() )
_age = newAge ;
}
However I would like to comment on this
void SetMyAge(int myAge){
this->myAge = myAge;
}
It is good practice to differentiate the nameing convention of the class varaiable to _myAge .
EDIT
I think the variable name was comprehended improperly .
myAge should be named _myAge .
I often see stuff like this:
class SomeClass {
public:
void someMethod();
private:
int someMember;
};
This seems totally unnatural to me (the same applies to case-statements when using switch). I expected something like this, when I started using C++ (it's been a long time since then, but I am still wondering):
class SomeClass {
public:
void someMethod();
private:
int someMember;
};
Is there a funded reason to break (otherwise) consistent indentation rules?
Increasing indentation normally reflects entry to a new nested scope, whereas both access specifiers and switch case statements don't vary the scope (the same is true of labels generally). Access specifiers can be optional in that you may start implementing a class or struct and have all members only need the implied access (i.e. private and public respectively), but then the code evolves and you need to add a specifier for the non-implied-access members: is it really worth having to suddenly change the indentation on all members? Again, there's no nested scope, so I think that would be actively misleading.
If you work on fixed-width terminals and wrap your lines accordingly, reindenting's a pain. But, it is useful to have the access specifiers stand out from the members, which means putting them back to the left somewhere - either in line with the class keyword or part-way there.
Personally, I do this:
class X
{
public:
int member_function()
{
switch (expression)
{
case X:
return 6;
default:
{
int n = get_value() / 6;
return n * n;
}
}
}
private:
int member_variable_;
};
Why do I not indent code for each case further? I can't claim what I do is particularly logical, but factors include:
I don't want to deemphasise the general switch/case indentation, as visually communicating the extent of the switch is important to quickly understanding the code
I'm happy just to put the { and } around existing case code - more like a comment "hey, I need a scope" - rather than feeling compelling to indent everything further, which doesn't make much sense even to me but kind of feels right - I like having the code for each case line up
some compilers do warn if you introduce new variables inside a case statement without introducing a scope, even if there are no cases when the variable is later used potentially uninitialised
I'm an 80-column coder generally, with 4 space indents normally, so being inside a switch - and thus obviously a function - means remaining columns are valuable.
Same for class/struct:
I want to scan the left column and quickly find the end of the class, or easily count the small classes on screen or in a printout; access specifiers at exactly the same indentation level deemphasise the class keyword, but it does help to have them visually distinct from the members (if the class/struct is more than a few lines, I also add a blank line beforehand)
I don't want to change existing class/struct member indentation when I introduce a private or protected specifier
In conclusion: lots of small factors go into developing people's indentation preferences, and if you want to be a C++ programmer in a corporate environment - especially a contractor - you just have to go with the flow and be able to change your own style sometimes too (e.g. I'm stuck in camelCaseLand right now, with public member variables starting with an uppercase letter - yikes!). Don't sweat it - it's not worth it.
The access specifiers are really just labels (as in those used by goto). People generally don't indent labels, or outdent them one level with respect to the surrounding code. So I would say this is not inconsistent at all.
The Standard also uses this style for access specifiers. Example from Chapter 10, paragraph 2:
class Base {
public:
int a, b, c;
};
Imagine such a class definition:
class SomeClass {
void ImplicitlyPrivateMethod();
public:
void someMethod();
private:
int someMember;
};
With the style of indentation you propose, one would need to change this into
class SomeClass {
void ImplicitlyPrivateMethod();
public:
void someMethod();
private:
int someMember;
};
(which looks not so nice to many people, especially if the "implicit" section is long enough).
I personally prefer half-indentation of such specifiers:
class SomeClass {
void ImplicitlyPrivateMethod();
public:
void someMethod();
private:
int someMember;
};
But this is a matter of personal taste.
As with many other things, it is important not to mistake the rule with the purpose. The purpose of indentation is making code clearer and easier to read by providing an extra visual hint on what belongs where. Now, in the particular cases you mention, together with namespaces, in many cases the extra indentation does not help in readability. The cases in a switch can be understood as if-elses, where you would not add the extra indentation. The cases are block delimiters similar to the curly braces.
switch ( var ) {
case 1: // if ( var == 1 ) {
code;
case 2: // } else if ( var == 2 ) {
code;
}
At class level, access modifiers can be considered to be block delimiters at the same level that the class braces. Adding an extra level of indentation does not make the code clearer:
class test {
public:
void foo();
private:
int member;
};
The same way goes with namespaces, where some people avoid indenting the whole namespace level. In all three cases, there is no clear advantage in adding the extra indentation and if you abide to short code lines (80/100 characters) and big enough indentation levels (8 or even 4 characters) then there might be an advantage to not indenting.
Personally, I never indent case or accessor modifiers, in the case of namespaces, it depends... a namespace that covers the whole source file will most probably not be indented, while namespaces that only take part of the source file will be indented --the rationale is that in the former case it adds no actual value, while in the second it does.
Two possible reasons:
that's how Bjarne Stroustrup indents them in his books
most text editors indent them that way automatically
Because public and private are labels which don't introduce a new scope, I prefer not to give them any special indentation, thus:
class foo {
public:
void something();
void something_else();
private:
int top_secret;
};
This way, the consistent indentation rule is "indentation equals scope".
It's all about scoping and grouping of branches. If these are not affected, then do not add an indentation level.
Take for instance the following:
if( test == 1 ) {
action1( );
} else if( test == 2 ) {
action2( );
} else {
action3( );
}
Take note of the levels of the statement blocks. Now re-write it as a case statement with indented cases:
switch( test ) {
case 1:
action1( );
break;
case 2:
action2( );
break;
default:
action3( );
break;
}
This does the exact same functionally, yet the indentations don't match of my actions. And I think it is this inconsistency that finally made me change to dropping the extra spurious indentation. (Even though I don't mind the half-indenting proposed by others, mind you.)
There are very few access modifier lines per class, and most editors color modifiers differently from everything else. They stand out plenty on their own, so adding tabs is unnecessary.
As mentioned earlier (though argued for non-indented access modifiers), access modifiers form logical blocks. While these are at the same level as the class braces, they are special.
Thus it's useful to have indentation to clearly show where each block starts and ends.
I personally think it makes the code clearer. Others will dissagree.
This is a rather subjective question.
Most editors indent them automatically. For me, I leave them as they are in small classes or small files or short switch statements, but for long ones or a long file with many long switch statements I use more indentation for easier readability.
I sometimes do this which I feel is as old style:
Class CClass
{
CClass();
~CClass();
Public:
int a;
Private:
int b;
};
CClass::CClass
{
TODO code;
}
This sometimes makes it easier when a file may contain more than 20 or 50 functions, so you can easily spot the beginning of every function.
Typically, the way I'd define a true global constant (lets say, pi) would be to place an extern const in a header file, and define the constant in a .cpp file:
constants.h:
extern const pi;
constants.cpp:
#include "constants.h"
#include <cmath>
const pi=std::acos(-1.0);
This works great for true constants such as pi. However, I am looking for a best practice when it comes to defining a "constant" in that it will remain constant from program run to program run, but may change, depending on an input file. An example of this would be the gravitational constant, which is dependent on the units used. g is defined in the input file, and I would like it to be a global value that any object can use. I've always heard it is bad practice to have non-constant globals, so currently I have g stored in a system object, which is then passed on to all of the objects it generates. However this seems a bit clunky and hard to maintain as the number of objects grow.
Thoughts?
It all depends on your application size. If you are truly absolutely sure that a particular constant will have a single value shared by all threads and branches in your code for a single run, and that is unlikely to change in the future, then a global variable matches the intended semantics most closely, so it's best to just use that. It's also something that's trivial to refactor later on if needed, especially if you use distinctive prefixes for globals (such as g_) so that they never clash with locals - which is a good idea in general.
In general, I prefer to stick to YAGNI, and don't try to blindly placate various coding style guides. Instead, I first look if their rationale applies to a particular case (if a coding style guide doesn't have a rationale, it is a bad one), and if it clearly doesn't, then there is no reason to apply that guide to that case.
I can understand the predicament you're in, but I am afraid that you are unfortunately not doing this right.
The units should not affect the program, if you try to handle multiple different units in the heart of your program, you're going to get hurt badly.
Conceptually, you should do something like this:
Parse Input
|
Convert into SI metric
|
Run Program
|
Convert into original metric
|
Produce Output
This ensure that your program is nicely isolated from the various metrics that exist. Thus if one day you somehow add support to the French metric system of the 16th century, you'll just add to configure the Convert steps (Adapters) correctly, and perhaps a bit of the input/output (to recognize them and print them correctly), but the heart of the program, ie the computation unit, would remain unaffected by the new functionality.
Now, if you are to use a constant that is not so constant (for example the acceleration of gravity on earth which depends on the latitude, longitude and altitude), then you can simply pass it as arguments, grouped with the other constants.
class Constants
{
public:
Constants(double g, ....);
double g() const;
/// ...
private:
double mG;
/// ...
};
This could be made a Singleton, but that goes against the (controversed) Dependency Injection idiom. Personally I stray away from Singleton as much as I can, I usually use some Context class that I pass in each method, makes it much easier to test the methods independently from one another.
A legitimate use of singletons!
A singleton class constants() with a method to set the units?
You can use a variant of your latter approach, make a "GlobalState" class that holds all those variables and pass that around to all objects:
struct GlobalState {
float get_x() const;
float get_y() const;
...
};
struct MyClass {
MyClass(GlobalState &s)
{
// get data from s here
... = s.get_x();
}
};
It avoids globals, if you don't like them, and it grows gracefully as more variables are needed.
It's bad to have globals which change value during the lifetime of the run.
A value that is set once upon startup (and remains "constant" thereafter) is a perfectly acceptable use for a global.
Why is your current solution going to be hard to maintain? You can split the object up into multiple classes as it grows (one object for simulation parameters such as your gravitational constant, one object for general configuration, and so on)
My typical idiom for programs with configurable items is to create a singleton class named "configuration". Inside configuration go things that might be read from parsed configuration files, the registry, environment variables, etc.
Generally I'm against making get() methods, but this is my major exception. You can't typically make your configuration items consts if they have to be read from somewhere at startup, but you can make them private and use const get() methods to make the client view of them const.
This actually brings to mind the C++ Template Metaprogramming book by Abrahams & Gurtovoy - Is there a better way to manage your data so that you don't get poor conversions from yards to meters or from volume to length, and maybe that class knows about gravity being a form acceleration.
Also you already have a nice example here, pi = the result of some function...
const pi=std::acos(-1.0);
So why not make gravity the result of some function, which just happens to read that from file?
const gravity=configGravity();
configGravity() {
// open some file
// read the data
// return result
}
The problem is that because the global is managed prior to main being called you cannot provide input into the function - what config file, what if the file is missing or doesn't have g in it.
So if you want error handling you need to go for a later initialization, singletons fit that better.
Let's spell out some specs. So, you want:
(1) the file holding the global info (gravity, etc.) to outlive your runs of the executable using them;
(2) the global info to be visible in all your units (source files);
(3) your program to not be allowed to change the global info, once read from the file;
Well,
(1) Suggests a wrapper around the global info whose constructor takes an ifstream or file name string reference (hence, the file must exist before the constructor is called and it will still be there after the destructor is invoked);
(2) Suggests a global variable of the wrapper. You may, additionally, make sure that that is the only instance of this wrapper, in which case you need to make it a singleton as was suggested. Then again, you may not need this (you may be okay with having multiple copies of the same info, as long as it is read-only info!).
(3) Suggests a const getter from the wrapper. So, a sample may look like this:
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>//for EXIT_FAILURE
using namespace std;
class GlobalsFromFiles
{
public:
GlobalsFromFiles(const string& file_name)
{
//...process file:
std::ifstream ginfo_file(file_name.c_str());
if( !ginfo_file )
{
//throw SomeException(some_message);//not recommended to throw from constructors
//(definitely *NOT* from destructors)
//but you can... the problem would be: where do you place the catcher?
//so better just display an error message and exit
cerr<<"Uh-oh...file "<<file_name<<" not found"<<endl;
exit(EXIT_FAILURE);
}
//...read data...
ginfo_file>>gravity_;
//...
}
double g_(void) const
{
return gravity_;
}
private:
double gravity_;
};
GlobalsFromFiles Gs("globals.dat");
int main(void)
{
cout<<Gs.g_()<<endl;
return 0;
}
Globals aren't evil
Had to get that off my chest first :)
I'd stick the constants into a struct, and make a global instance of that:
struct Constants
{
double g;
// ...
};
extern Constants C = { ... };
double Grav(double m1, double m2, double r) { return C.g * m1 * m2 / (r*r); }
(Short names are ok, too, all scientists and engineers do that.....)
I've used the fact that local variables (i.e. members, parameters, function-locals, ..) take precedence over the global in a few cases as "apects for the poor":
You could easily change the method to
double Grav(double m1, double m2, double r, Constants const & C = ::C)
{ return C.g * m1 * m2 / (r*r); } // same code!
You could create an
struct AlternateUniverse
{
Constants C;
AlternateUniverse()
{
PostulateWildly(C); // initialize C to better values
double Grav(double m1, double m2, double r) { /* same code! */ }
}
}
The idea is to write code with least overhead in the default case, and preserving the implementation even if the universal constants should change.
Call Scope vs. Source Scope
Alternatively, if you/your devs are more into procedural rather thsn OO style, you could use call scope instead of source scope, with a global stack of values, roughly:
std::deque<Constants> g_constants;
void InAnAlternateUniverse()
{
PostulateWildly(C); //
g_constants.push_front(C);
CalculateCoreTemp();
g_constants.pop_front();
}
void CalculateCoreTemp()
{
Constants const & C= g_constants.front();
// ...
}
Everything in the call tree gets to use the "most current" constants. OYu can call the same tree of coutines - no matter how deeply nested - with an alternate set of constants. Of course it should be encapsulated better, made exception safe, and for multithreading you need thread local storage (so each thread gets it's own "stack")
Calculation vs. User Interface
We approach your original problem differently: All internal representation, all persistent data uses SI base units. Conversion takes place at input and output (e.g. even though the typical size is millimeter, it's always stored as meter).
I can't really compare, but worksd very well for us.
Dimensional Analysis
Other replies have at least hinted at Dimensional Analysis, such as the respective Boost Library. It can enforce dimensional correctness, and can automate the input / output conversions.
Setting:
A pseudo-random pattern has to be generated. There are several ways / or algorithms availible to create different content. All algorithms will generate a list of chars (but could be anything else)... the important part is, that all of them return the same type of values, and need the same type of input arguments.
It has to be possible to call a method GetRandomPattern(), which will use a random one of the algorithms everytime it is called.
My first aproach was to put each algorithm in it's own function and select a random one of them each time GetRandompattern() is called. But I didn't come up with another way of choosing between them, than with a switch case statement which is unhandy, ugly and inflexible.
class PatternGenerator{
public:
list<char> GetRandomPattern();
private:
list<char>GeneratePatternA(foo bar);
list<char>GeneratePatternB(foo bar);
........
list<char>GeneratePatternX(foo bar);
}
What would be a good way to select a random GeneratePattern function every time the GetRandomPattern() method is called ?
Or should the whole class be designed differently ?
Thanks a lot
Create a single class for each algorithm, each one subclassing a generator class. Put instances of those objects into a list. Pick one randomly and use it!
More generically, if you start creating several alternative methods with the same signature, something's screaming "put us into sibling classes" at you :)
Update
Can't resist arguing a bit more for an object-oriented solution after the pointer-suggestion came
Imagine at some point you want to print which method created which random thing. With objects, it's easy, just add a "name" method or something. How do you want to achieve this if all you got is a pointer? (yea, create a dictionary from pointers to strings, hm...)
Imagine you find out that you got ten methods, five of which only differ by a parameter. So you write five functions "just to keep the code clean from OOP garbage"? Or won't you rather have a function which happens to be able to store some state with it (also known as an object?)
What I'm trying to say is that this is a textbook application for some OOP design. The above points are just trying to flesh that out a bit and argue that even if it works with pointers now, it's not the future-proof solution. And you shouldn't be afraid to produce code that talks to the reader (ie your future you, in four weeks or so) telling that person what it's doing
You can make an array of function pointers. This avoids having to create a whole bunch of different classes, although you still have to assign the function pointers to the elements of the array. Any way you do this, there are going to be a lot of repetitive-looking lines. In your example, it's in the GetRandomPattern method. In mine, it's in the PatternGenerator constructor.
#define FUNCTION_COUNT 24
typedef list<char>(*generatorFunc)(foo);
class PatternGenerator{
public:
PatternGenerator() {
functions[0] = &GeneratePatternA;
functions[1] = &GeneratePatternB;
...
functions[24] = &GeneratePatternX;
}
list<char> GetRandomPattern() {
foo bar = value;
int funcToUse = rand()%FUNCTION_COUNT;
functions[funcToUse](bar);
}
private:
generatorFunc functions[FUNCTION_COUNT];
}
One way to avoid switch-like coding is using Strategy design pattern. As example:
class IRandomPatternGenerator
{
public:
virtual list<int> makePattern(foo bar);
};
class ARandomPatternGenerator : public IRandomPatternGenerator
{
public:
virtual list<int> makePattern(foo bar)
{
...
}
};
class BRandomPatternGenerator : public IRandomPatternGenerator
{
public:
virtual list<int> makePattern(foo bar)
{
...
}
};
Then you can choose particular algorithm depending on runtime type of your RandomPatternGenerator instance. (As example creating list like nicolas78 suggested)
Thank you for all your great input.
I decided to go with function pointers, mainly because I didn't know them before and they seem to be very powerfull and it was a good chance to get to know them, but also because it saves me lot of lines of code.
If I'd be using Ruby / Java / C# I'd have decided for the suggested Strategy Design pattern ;-)
class PatternGenerator{
typedef list<char>(PatternGenerator::*createPatternFunctionPtr);
public:
PatternGenerator(){
Initialize();
}
GetRandomPattern(){
int randomMethod = (rand()%functionPointerVector.size());
createPatternFunctionPtr randomFunction = functionPointerVector.at( randomMethod );
list<char> pattern = (this->*randomFunction)();
return pattern;
}
private:
void Initialize(){
createPatternFunctionPtr methodA = &PatternGenerator::GeneratePatternA;
createPatternFunctionPtr methodB = &PatternGenerator::GeneratePatternB;
...
functionPointerVector.push_back( methodA );
functionPointerVector.push_back( methodB );
}
list<char>GeneratePatternA(){
...}
list<char>GeneratePatternB(){
...}
vector< createPattern > functionPointerVector;
The readability is not much worse as it would have been with the Design Pattern Solution, it's easy to add new algorithms, the pointer arithmetics are capsuled within a class, it prevents memory leaks and it's very fast and effective...