I have a quite huge/involved class C (quite difficult to refactor as no one ever tried to do so since 15 years, so that things have piled up to the rafters, plus bad design) containing an int member variable called let's say m_Toto. Whenever you instantiate an object from C, you pass by an init() member function that sets a lot of things, among them it sets m_Toto to 0. After some data member have been set and used, on can calculate the value that m_Toto is going to have. This value will be central to everything else the class does.
Now, bad naming set aside, m_Toto is calculated for the first time through the call of the int C::GetToto(), which has this structure :
int C::GetToto()
{
if (m_Toto != 0)
return m_Toto ;
// else
// we calculate m_Toto thx to a lot of data etc
}
Whenever we need m_Toto's value, we call GetToto(), who checks that m_Toto is initialized (i.e. is non zero), and returns, the "real" calculation being done the first time only.
My problem is the following. I have a state of C that is defined by a bool member variable m_IsBlah, and which should be determined thx to the value of m_Toto.
How could I do to be sure, in a elegant way, to be sure that m_IsBlah will be calculated only the first time m_Toto is calculated, and only then, without resorting to ugly if's of the above kind ? Or is it too much overkill ?
As always with C++, use classes to capture abstractions. Have the class as a member of C contructed in its constructor and reports if and when IsBlah is set and if so to what.
Related
I have a confusion about C++ function/method design as below:
1.
class ArithmeticCalculation
{
private:
float num1_;
float num2_;
float sum_;
void addTwoNumbers();
};
2.
class ArithmeticCalculation
{
private:
float addTwoNumbers(float num1, float num2);
};
In 1., one can basically declare a class variable and the void addTwoNumbers() will just implement it and assign to the class variable (sum_). I found using 1. is cleaner but using 2. looks like it more intuitive for function use.
Which one is actually best option considering the function/method is not restricted to only this basic addition functionality -- I mean in general how to decide to use with return or simply void?
The major difference between the two functions is that the second one is stateless*, while the first one has a state. Other things being equal, stateless approach is preferred, because it gives the users of your class more flexibility at utilizing your class in their systems. For example, stateless functions are re-entrant, while functions that rely on state may require the code that uses them to take additional measures that prevent incorrect use.
Re-entrancy alone is a big reason to prefer stateless functions whenever possible. However, there are situations when keeping state becomes more economical - for example, when you are using Builder Design Pattern.
Another important advantage of keeping your functions stateless whenever it is possible is that the call sequence becomes more readable. A call of a method that relies on the state consists of these parts:
Set up the object before the call
Make the call
Harvest the result of the call (optional)
Human readers of your code will have much easier time reading the call that uses a function invocation with parameter passing than the three-part setup-call-get result sequence.
There are situations when you have to have state, for example, when you want to defer the action. In this case the parameters are supplied by one part of the code, while the computation is initiated by some other part of the code. In terms of your example, one function would call set_num1 and set_num2, while another function would call addTwoNumbers at some later time. In situations like this you could save the parameters on the object itself, or create a separate object with deferred parameters.
* This is only an assumption based on the signature of your member function. Your second function gets all the data that it needs as parameters, and returns the value to the caller; Obviously, implementations may choose to add some state, e.g. by saving the last result, but that is uncommon for addTwoNumbers functions, so I assume that your code does not do it.
The first function doesn't really make a lot of sense. What numbers? Where does the result go? The name doesn't describe the expected side-effects, nor the origin of the numbers in question.
The second function makes it abundantly clear what's going on, where the result is, and how that function might be used.
Your functions should strive to communicate their intent based on the function signature. If that's not sufficient you'll need to add comments or documentation, but no amount of commenting or documentation can pave over a misleading or confusing signature.
Think about what your function's responsibility is as well as whatever expectations it has when naming things. For example:
void whatever(const int);
What does that function do? Could you even guess without looking at code or documentation?
Compare with the same function given a much more meaningful name:
void detonateReactor(const int countdownTimeInSeconds);
It seems pretty clear what that does now, as well as what side-effects it will have.
You probably had in mind something like this for the first option:
struct Adder {
float sum;
float a;
float b;
void addNumbers(){ sum = a+b; }
};
that would be used like this:
Adder adder;
adder.a = 1.0;
adder.b = 2.0;
adder.addNumbers();
std::cout << adder.sum << "\n";
There is no single good argument to do this when you actually wanted this:
float addTwoNumbers(float a,float b) { return a+b; }
std::cout << addTwoNumbers(1.0,2.0) << "\n";
Not everything has to be inside a class. Actually not everything should be inside a class (C++ isnt Java). If you need a function that adds two numbers then write a function that adds two numbers and dont overthink it.
So I'm working on a 2D space simulator and I have the resource manager 'calc' that handles all calculations for everything. For example, from calc.hpp:
var calc::eccentricity (object A, object B);
var calc::distance (object A, object B);
var calc::orbitV (object A, object B);
etc. However, the way I have my program structured is in my calc class I have
private:
object *ship //the currently controlled ship
object *targ //target
object *ref //reference (from which speeds, position, etc. are calculated)
and to use the calculations given in the first example with these, I write three functions for each calculation function, like so:
var calc::ship_ecc (object A){
if(!ship) //catches null pointers
return NAN;
return eccentricity(*ship, A);
}
var calc::ship_ref_ecc (){
if(!ref) //catches null pointers
return NAN;
return ship_ecc(*ref);
}
var calc::ship_targ_ecc (){
if(!targ) //catches null pointers
return NAN;
return ship_ecc(*targ);
}
for eccentricity, and then the same for distance and orbitV. So I end up having four functions for every calculation. As you can see from calc.hpp this makes for plenty of duplicated code. And duplicated code is a Bad Thing.
What my question is
Is there some way to call
calc.ship.targ.eccentricity();
calc.ship.ref.eccentricity(); //or variation thereof
or
calc.ship.targ(eccentricity);
calc.ship.ref(eccentricity); //or variation thereof
instead of
calc.ship_targ_ecc();
calc.ship_ref_ecc();
? I'm wondering if you could do some fancy operator() overloading, or pass a function, or make a friend class in calc. Ideally I should only be able to access lines 31 - 53, which are all public.
Thanks!
EDIT: got an example for yall: https://ideone.com/jypJQS this is what it should output and how it is working now
Maybe this changes too much your current code. But I think that the functions in calc should be members of object. So you could things like :
ship.eccentricity(target);
What confuses me (and what is probably the big problem here) is that you seem to define some hard relations in your calc object (the private members). What are those for ? From the code, I guess there is a calc object for every "ship". If yes, it would be an other reason to add the code to object instead of maintaining 1-1 relations between object and calc.
This might require a little bit of refactoring, but I think it's worth it. For a simple game, you can use OOP and Polymorphism to fix the issue.
First of all, create an object class.
class Object {
public:
Object();
~Object();
};
This object class would be a basis for all your objects in the game (ship, character, etc...). You, then, would create a sub class for your ship.
class Ship : public Object {
};
This would allow an easy expansion to future objects that require the same principle.
In the object class, you would have some basic properties:
physical (optional)
dimensions
speed (last calculated speed)
controlled (bool - current controlling ship or not)
This would eliminate the need to have hard relationships with the calc and ship class.
Next, you would change your calc class to become general. You don't want to depend on a single ship object, this is cumbersome.
Option 1
You could create an instance of the calc class for each object. This calc instance would have access to the already available properties of the object and ship class.
Option 2
Create a general calc class that would require you to pass a reference to the ship/object instance. calc->eccentricity(&ship, target);
Option 3
Within a possible manager class, or a simple "global" variable. You could hold a reference to the currently controlled ship (if that's how your system works, I'm not sure). Or you could store the index of the ship and all instances are held inside a vector<&Ship>.
In a simplistic game, straight forward OOP will suffice, but if you want more decoupling, component based game design would be a better bet (in combination with OOP, of course).
So I took this over to /r/learnprogramming, and I got a good answer from zzyzzyxx (as always). His answer:
What's wrong with simply having functions that take the required two or three parameters? They don't have to be in any special calc class. Maybe a calc namespace. I'm not sure it makes sense with the rest of your design, but what about making it a member function so that anything can calculate what it needs given a target and potentially a reference point if there's no sensible default?
So basically, don't worry about all this calc.eccentricity(A, B), calc.ship_ecc(A), calc.ship_ref_ecc() business, just say
calc.eccentricity(*calc.targ(), B)
Also, don't make calc a singleton, make it a namespace.
I'll go do that now.
I have started a migration of a high energy physics algorithm written in FORTRAN to an object oriented approach in C++. The FORTRAN code uses a lot of global variables all across a lot of functions.
I have simplified the global variables into a set of input variables, and a set of invariants (variables calculated once at the beginning of the algorithm and then used by all the functions).
Also, I have divided the full algorithm into three logical steps, represented by three different classes. So, in a very simple way, I have something like this:
double calculateFactor(double x, double y, double z)
{
InvariantsTypeA invA();
InvariantsTypeB invB();
// they need x, y and z
invA.CalculateValues();
invB.CalculateValues();
Step1 s1();
Step2 s2();
Step3 s3();
// they need x, y, z, invA and invB
return s1.Eval() + s2.Eval() + s3.Eval();
}
My problem is:
for doing the calculations all the InvariantsTypeX and StepX objects need the input parameters (and these are not just three).
the three objects s1, s2 and s3 need the data of the invA and invB objects.
all the classes use several other classes through composition to do their job, and all those classes also need the input and the invariants (by example, s1 has a member object theta of class ThetaMatrix that needs x, z and invB to get constructed).
I cannot rewrite the algorithm to reduce the global values, because it follows several high energy physics formulas, and those formulas are just like that.
Is there a good pattern to share the input parameters and the invariants to all the objects used to calculate the result?
Should I use singletons? (but the calculateFactor function is evaluated around a million of times)
Or should I pass all the required data as arguments to the objects when they are created?(but if I do that then the data will be passed everywhere in every member object of every class, creating a mess)
Thanks.
Well, in C++ the most suitable solution, given your constraints and conditions, is represented by pointers. Many developers told you to use boost::shared_ptr. Well it is not necessary, although it provides a better performance especially when considering portability and robustness to system faults.
It is not necessary for you to bind to boost. It is true that they are not compiled and that now standardization processes will lead to c++ with boost directly integrated as a standard library, but if you do not want to use an external library you obviously can.
So let's go and try to solve your problem using just C++ and what it provides actually.
You'll probably have a main method and there, you told before, initialize all invariants elements... so you basically have constants and they can be every possible type. no need to make them constant if you want, however, in main you instantiate your invariant elements and point them for all those components requiring their usage. First in a separate file called "common_components.hpp" consider the following (I assume that you need some types for your invariant variables):
typedef struct {
Type1 invariant_var1;
Type2 invariant_var2;
...
TypeN invariant_varN;
} InvariantType; // Contains the variables I need, it is a type, instantiating it will generate a set of global variables.
typedef InvariantType* InvariantPtr; // Will point to a set of invariants
In your "main.cpp" file you'll have:
#include "common_components.hpp"
// Functions declaration
int main(int, char**);
MyType1 CalculateValues1(InvariantPtr); /* Your functions have as imput param the pointer to globals */
MyType2 CalculateValues2(InvariantPtr); /* Your functions have as imput param the pointer to globals */
...
MyType3 CalculateValuesN(InvariantPtr); /* Your functions have as imput param the pointer to globals */
// Main implementation
int main(int argc, char** argv) {
InvariantType invariants = {
value1,
value2,
...
valueN
}; // Instantiating all invariants I need.
InvariantPtr global = &invariants;
// Now I have my variable global being a pointer to global.
// Here I have to call the functions
CalculateValue1(global);
CalculateValue2(global);
...
CalculateValueN(global);
}
If you have functions returning or using the global variable use the pointer to the struct modifying you methods' interface. By doing so all changes will be flooded to all using thoss variables.
Why not passing the invariants as a function parameter or to the constructor of the class having the calculateFactor method ?
Also try to gather parameters together if you have too many params for a single function (for instance, instead of (x, y, z) pass a 3D point, you have then only 1 parameter instead of 3).
three logical steps, represented by three different classes
This may not have been the best approach.
A single class can have a large number of "global" variables, shared by all methods of the class.
What I've done when converting old codes (C or Fortran) to new OO structures is to try to create a single class which represents a more complete "thing".
In some case, well-structured FORTRAN would use "Named COMMON Blocks" to cluster things into meaningful groups. This is a hint as to what the "thing" really was.
Also, FORTRAN will have lots of parallel arrays which aren't really separate things, they're separate attributes of a common thing.
DOUBLE X(200)
DOUBLE Y(200)
Is really a small class with two attributes that you would put into a collection.
Finally, you can easily create large classes with nothing but data, separate from the the class that contains the functions that do the work. This is kind of creepy, but it allows you to finesse the common issue by translating a COMMON block into a class and simply passing an instance of that class to every function that uses the COMMON.
There is a very simple template class to share data between objects in C++ and it is called shared_ptr. It is in the new STL and in boost.
If two objects both have a shared_ptr to the same object they get shared access to whatever data it holds.
In your particular case you probably don't want this but want a simple class that holds the data.
class FactorCalculator
{
InvariantsType invA;
InvariantsType invB;
public:
FactorCalculator() // calculate the invariants once per calculator
{
invA.CalculateValues();
invB.CalculateValues();
}
// call multiple times with different values of x, y, z
double calculateFactor( double x, double y, double z ) /*const*/
{
// calculate using pre-calculated values in invA and invB
}
};
Instead of passing each parameter individually, create another class to store them all and pass an instance of that class:
// Before
void f1(int a, int b, int c) {
cout << a << b << c << endl;
}
// After
void f2(const HighEnergyParams& x) {
cout << x.a << x.b << x.c << endl;
}
First point: globals aren't nearly as bad (in themselves) as many (most?) programmers claim. In fact, in themselves, they aren't really bad at all. They're primarily a symptom of other problems, primarily 1) logically separate pieces of code that have been unnecessarily intermixed, and 2) code that has unnecessary data dependencies.
In your case, it sounds like already eliminated (or at least minimized) the real problems (being invariants, not really variables eliminates one major source of problems all by itself). You've already stated that you can't eliminate the data dependencies, and you've apparently un-mingled the code to the point that you have at least two distinct sets of invariants. Without seeing the code, that may be coarser granularity than really needed, and maybe upon closer inspection, some of those dependencies can be eliminated completely.
If you can reduce or eliminate the dependencies, that's a worthwhile pursuit -- but eliminating the globals, in itself, is rarely worthwhile or useful. In fact, I'd say within the last decade or so, I've seen fewer problems caused by globals, than by people who didn't really understand their problems attempting to eliminate what were (or should have been) perfectly fine as globals.
Given that they are intended to be invariant, what you probably should do is enforce that explicitly. For example, have a factory class (or function) that creates an invariant class. The invariant class makes the factory its friend, but that's the only way members of the invariant class can change. The factory class, in turn, has (for example) a static bool, and executes an assert if you attempt to run it more than once. This gives (a reasonable level of) assurance that the invariants really are invariant (yes, a reinterpret_cast will let you modify the data anyway, but not by accident).
The one real question I'd have is whether there's a real point in separating your invariants into two "chunks" if all the calculations really depend on both. If there's a clear, logical separation between the two, that's great (even if they do get used together). If you have what's logically a single block of data, however, trying to break it into pieces may be counterproductive.
Bottom line: globals are (at worst) a symptom, not a disease. Insisting that you're going to get the patient's temperature down to 98.6 degrees may be counterproductive -- especially if the patient is an animal whose normal body temperature is actually 102 degrees.
uhm. Cpp is not necessarily object oriented. It is the GTA of programming! You are free to be a Object obscessed freak, a relax C programmer, a functional programmer, what ever; a mix martial artist.
My point, if Global variables worked in your fortran compile, just copy and paste to Cpp. No need to avoid global variables. It follows the principle of, dont touch legacy code.
Lets understand why global variables may cause problem. As you know, variables is the programs`s state and state is the soul of the program. Bad or invalid state causes runtime and logic errors. The problem with global variables/ global state, is that any part of our code has access to it; thus in case of invalid state, their are many bad guys or culprits to consider, meaning functions and operators. However this is only applicable if you really used so many functions on your global variable. I mean you are the only one working on your lonely program. Global variables are only a real problem if you are doing a team project. In that case many people have access to it, writing different functions that may or may not be accessing that variable.
I have created a class that models time slots in a variable-granularity daily schedule, where, for example, the first time slot is 30 minutes, but the second time slot can be 40 minutes and the first available slot starts at (a value comparable to) 1.
What I want to do now is to define somehow the maximum and minimum allowable values that this class takes and I have two practical questions in order to do so:
1.- Does it make sense to define absolute minimum and maximum in such a way for a custom class? Or better, does it suffice that a value always compares as lower-than any other possible value of the type, given the class's defined relational operators, to be defined the min? (and analogusly for the max)
2.- Assuming the previous question has an answer modeled after "yes" (or "yes but ..."), how do I define such max/min? I know that there is std::numeric_limits<> but from what I read it is intended for "numeric types". Do I interpret that as meaning "represented as a number" or can I make a broader assumption like "represented with numbers" or "having a correspondence to integers"? After all, it would make sense to define the minimum and maximum for a date class, and maybe for a dictionary class, but numeric_limits may not be intended for those uses (I don't have much experience with it). Plus, numeric_limits has a lot of extra members and information that I don't know what to make with. If I don't use numeric_limits, what other well-known / widely-used mechanism does C++ offer to indicate the available range of values for a class?
Having trouble making sense of your question. I think what you're asking is whether it makes sense to be assertive about the class's domain (that data which can be fed to it and make sense), and if so how to be assertive.
The first has a very clear answer: yes, absolutely. You want your class to be, "...easy to use correctly and difficult to use incorrectly." This includes making sure the clients of the class are being told when they do something wrong.
The second has a less clear answer. Much of the time you'll simply want to use the assert() function to assert a function or class's domain. Other times you'll want to throw an exception. Sometimes you want to do both. When performance can be an issue sometimes you want to provide an interface that does neither. Usually you want to provide an interface that can at least be checked against so that the clients can tell what is valid/invalid input before attempting to feed it to your class or function.
The reason you might want to both assert and throw is because throwing an exception destroys stack information and can make debugging difficult, but assert only happens during build and doesn't actually do anything to protect you from running calculations or doing things that can cause crashes or invalidate data. Thus asserting and then throwing is often the best answer so that you can debug when you run into it while testing but still protect the user when those bugs make it to the shelf.
For your class you might consider a couple ways to provide min/max. One is to provide min/max functions in the class's interface. Another might be to use external functionality and yes, numeric_limits might just be the thing since a range is sometimes a type of numeric quantity. You could even provide a more generic interface that has a validate_input() function in your class so that you can do any comparison that might be appropriate.
The second part of your question has a lot of valid answers depending on a lot of variables including personal taste.
As the designer of your schedule/slot code, it's up to you as to how much flexibility/practicality you want.
Two simple approaches would be to either define your own values in that class
const long MIN_SLOT = 1;
const long MAX_SLOT = 999; // for example
Or define another class that holds the definitions
class SchedLimits{
public:
const static long MIN_SLOT = 1;
const static long MAX_SLOT = 999;
}
Simplest of all would be enums. (my thanks to the commenter that reminded me of those)
enum {MIN_SLOT = 1, MAX_SLOT = 999};
Just create some const static members that reflect the minimums and maximums.
Obviously the point of using named constants over magic numbers is for code clarity and for not having to go through code changing numbers throughout.
However, what do you do if you just have a number used just once in a function? Say you have a short member function that uses an object's velocity (which we'll say won't change) to calculate its motion, but this is the only function that uses that velocity. Would you...
A) Give the class a named static constant to use
B) Put a named constant in the function
C) Use the magic number but comment it
D) Other...
I am kind of leaning towards using a magic number and commenting it if the number is ONLY BEING USED ONCE, but I'd like to hear others' thoughts.
Edit: Does putting a named constant in a function called many times and assigning to it have performance implications? If it does I guess the best approach would be to put the constant in a namespace or make it a class variable, etc.
Just move it up:
void do_something(void)
{
const float InitialVelocity = 5.0f;
something = InitialVelocity;
// etc.
}
Say you have a short member function
that uses an object's velocity
You said it, the constant has a name:
const type object_velocity = ....;
Magic numbers are my enemies :)
I'd use a function-local named constant, at a minimum. Usually I'd use an anonymous namespace named constant to make the value available throughout the source file, assuming that it might be useful later to other functions.
Use Eclipses refactoring functions to move the constant into a named variable of the method.
Use it as a constant inside the function:
const int x = myMagicNumber; //Now document the magic.