I'm currently implementing some algorithms into an existing program. Long story short, I created a new class, "Adder". An Adder is a member of another class representing the physical object actually doing the calculus , which calls adder.calc() with its parameters (merely a list of objects to do the maths on).
To do these maths, I need some parameters, which do not exist outside of the class (but can be set, see below). They're neither config parameters nor members of other classes. These parameters are D1 and D2, distances, and three arrays of fixed size: alpha, beta, delta.
I know some of you are more comfortable reading code than reading text so here you go:
class Adder
{
public:
Adder();
virtual Adder::~Adder();
void set( float d1, float d2 );
void set( float d1, float d2, int alpha[N_MAX], int beta[N_MAX], int delta[N_MAX] );
// Snipped prototypes
float calc( List& ... );
// ...
inline float get_d1() { return d1_ ;};
inline float get_d2() { return d2_ ;};
private:
float d1_;
float d2_;
int alpha_[N_MAX]; // A #define N_MAX is done elsewhere
int beta_[N_MAX];
int delta_[N_MAX];
};
Since this object is used as a member of another class, it is declared in a *.h:
private:
Adder adder_;
By doing that, I couldn't initialize the arrays (alpha/beta/delta) directly in the constructor ( int T[3] = { 1, 2, 3 }; ), without having to iterate throughout the three arrays. I thought of putting them in static const, but I don't think that's the proper way of solving such problems.
My second guess was to use the constructor to initialize the arrays:
Adder::Adder()
{
int alpha[N_MAX] = { 0, -60, -120, 180, 120, 60 };
int beta[N_MAX] = { 0, 0, 0, 0, 0, 0 };
int delta[N_MAX] = { 0, 0, 180, 180, 180, 0 };
set( 2.5, 0, alpha, beta, delta );
}
void Adder::set( float d1, float d2 ) {
if (d1 > 0)
d1_ = d1;
if (d2 > 0)
d2_ = d2;
}
void Adder::set( float d1, float d2, int alpha[N_MAX], int beta[N_MAX], int delta[N_MAX] ) {
set( d1, d2 );
for (int i = 0; i < N_MAX; ++i) {
alpha_[i] = alpha[i];
beta_[i] = beta[i];
delta_[i] = delta[i];
}
}
Would it be better to use another function (init()) which would initialize the arrays? Or is there a better way of doing that?
Did you see some mistakes or bad practice along the way?
You have chosen a very wide subject, so here is a broader answer.
Be aware of your surroundings
Too often I have seen code doing the same thing as elsewhere in the codebase. Make sure that the problem you are trying to solve has not already been solved by your team-mates or predecessors.
Try not to reinvent the wheel
An extension of my previous point.
While everyone should probably write a linked-list or a string class as an exercise, there is no need to write one for production code. You will have access to MFC, OWL, STL, Boost, whatever. If the wheel has already been invented, use it and get on with coding a solution to the real problem!
Think about how you are going to test your code
Test Driven Development (TDD) is one way (but not the only way) to ensure that your code is both testable and tested. If you think about testing your code from the beginning, it will be very easy to test. Then test it!
Write SOLID code
The Wikipedia page explains this far better than I could.
Ensure your code is readable
Meaningful identifiers are just the beginning. Unnecessary comments can also detract from readability as can long functions, functions with long argument lists (such as your second setter), etcetera. If you have coding standards, stick to them.
Use const more
My major gripe with C++ is that things aren't const by default! In your example, your getters should be declared const and your setters should have their arguments passed in as const (and const-reference for the arrays).
Ensure your code is maintainable
Unit tests (as mentioned above) will ensure that the next person to change your code doesn't break your implementation.
Ensure your library is usable
If you follow Principle of least astonishment and document your library with unit-tests, programmers using it will have fewer issues.
Refactor mercilessly
An extension of the previous point. Do everything you can to reduce code duplication. Today I witnessed a bug-fix that had to be executed in fifteen separate places (and was only executed in thirteen of these).
When creating an object I would advise to always give the user an complete object, with all member properly initialized. An Init method fails in doing that, making room for a common error, failing to calling the initializing function in a two phase initialization object. To prevent this either make your constructor private and use a builder function or a factory which in turn has access to the init method, or make init private and use it in the constructor. The last advice is generally the same as doing the initialization in the constructor, but it allows several constructors to use the same initializing action.
Okay.
I would:
Set the arrays to a known state by
using memset to clear all values to
0 (or some other value) within the
constructor before they are used.
Change the constructor to allow the
passing of array pointers that can
be used to initialise the arrays to
some other values.
Retain the Set
function that you have to change the
values within the arrays and
ariables that you're using.
Don't use virtual functions, unless your design actually requires them.
In a class that exists primarily to execute one function, that function is canonically named operator(). I.e. you'd call yours as adder_(params), not adder_.calc(params).
If you're initializing three arrays, it's more efficient to use three for-loops. (cache friendly)
Related
I want to initialise a lot of variables (doubles and ints mostly, but some vectors as well), which will then be passed into lots of functions. What is the best way to initialise these?
I could initialise them all in the main function, this just feels a little messy, and ideally I wanted to create a separate function to initialise them in. I want to try and keep the main function as empty as I can. However, I then have the issue of not being able to return them.
Is there a proper way of doing this? I've heard of constructors, but I'm not entirely sure what they're used for, and whether or not they're something that I should be looking at here.
1) you can use function, pass variable by reference for initialisation to keep main function clean.
2) you can use templates as mention in this video .
See the code.
Based on your requirements, I would use structs with default values:
struct MyConfiguration {
double someValue{ 5. };
int someOtherValue{ 3 };
};
int main( int, char ** ) {
const MyConfiguration c;
f( c.someValue );
g( c.someValue, c.someOtherValue );
}
For many kinds of applications it would be reasonable to read those values from a configuration file.
I have an assignment (see below for question) for a beginners c++ class, where i am asked to pass 2 values back from a single function. I am pretty sure of my understanding of how to use functions and the general structure of what the program should be, but i am having trouble fingin how to pass two variables back to "main" from the function.
Assignment:
Write a program that simulates an airplane race. The program will display a table showing the speed in km/hour and distance in km traveled by two airplanes every second until one of them has gone 10 kilometers.
These are the requirements for the program:
-The program will use a function that has the following parameters: time and acceleration.
-The function will pass back two data items: speed and distance.
You have two options (well, three really, but I'm leaving pointers out).
Take references to output arguments and assign them within the function.
Return a data structure which contains all of the return values.
Which option is best depends on your program. If this is a one off function that isn't called from many places then you may chose to use option #1. I assume by "speed" you mean the "constant velocity" which is reached after "time" of acceleration.
void calc_velocity_profile(double accel_time,
double acceleration,
double &out_velocity, // these last two are
double &out_distance); // assigned in the function
If this is a more general purpose function and/or a function which will be called by many clients I would probably prefer option #2.
struct velocity_profile {
double velocity;
double distance;
};
velocity_profile calc_velocity_profile(double accel_time, double acceleration);
Everything being equal, I prefer option 1. Given the choice, I like a function which returns a value instead of a function which mutates its input.
2017 Update: This is discussed in the C++ Core Guidelines :
F.21 To return multiple "out" values, prefer returning a tuple or struct
However, I would lean towards returning a struct over a tuple due to named, order-independent access that is encapsulated and reusable as a explicit strong type.
In the special case of returning a bool and a T, where the T is only filled if the bool is true , consider returning a std::optional<T>. See this CPPCon17 video for an extended discussion.
Struct version:
struct SpeedInfo{
float speed;
float distance;
};
SpeedInfo getInfo()
{
SpeedInfo si;
si.speed = //...
si.distance = //...
return si;
}
The benefit of this is that you get an encapsulated type with named access.
Reference version:
void getInfo(float& speed, float& distance)
{
speed = //...
distance = //...
}
You have to pass in the output vars:
float s;
float d;
getInfo(s, d);
Pointer version:
void getInfo(float* speed, float* distance)
{
if(speed)
{
*speed = //...
}
if(distance)
{
*distance= //...
}
}
Pass the memory address of the output variable:
float s;
float d;
getInfo(&s, &d);
Pointer version is interesting because you can just pass a nullptr/NULL/0 for things you aren't interested in; this can become useful when you are using such a function that potentially takes a lot of params, but are not interested in all the output values. e.g:
float d;
getInfo(nullptr, &d);
This is something which you cant do with references, although they are safer.
There is already such a data structure in C++ that is named as std::pair. It is declared in header <utility>. So the function could look the following way
std::pair<int, int> func( int time, int acceleration )
{
// some calculations
std::pair<int, int> ret_value;
ret_value.first = speed_value;
ret_value.second = distance_value;
return ( ret_value );
}
Having problems with array of pointers.
I have a custom class called C. C has a variable double c1. I have to sort an array of C-s by c1 using a custom written sorting algorithm. I am guessing that since I have to move objects in array, it would be much more eficient to just move pointers to objects, therefore I have to use not an array of objects, but an array of pointers to objects.
I initialized the array like that:
C** someC;
someC = new C*[size];
for(int i = 0; i < size; i++) {
// a and b are of type CPoint
someC[i] = new C(a,b);
}
Am I doing this part correctly? It is the calling of C objects that then causes problems:
someC[i]->a.x
gives me an error: left of '->a' must point to class/struct/union/generic type
I am new to C++ so I may be missing something obvious, but I did some research and did not find anything. Maybe I am not understanding well how pointers work...
UPDATE
The header file of C class:
#pragma once
class C
{
public:
CPoint a;
CPoint b;
double c1;
C(void);
C(CPoint,CPoint);
~C(void);
};
the implementation:
#include "StdAfx.h"
#include "C.h"
#include <math.h>
C::C(void)
{
}
C::C(CPoint a, CPoint b)
{
this->a=a;
this->b=b;
double c1_x = a.x - b.x;
double c1_y = a.y - b.y;
c1= sqrt( (c1_x * c1_x) + (c1_y * c1_y));
}
C::~C(void)
{
}
UPDATE
The problem was in the code I provided in the comments, I did not notice I was calling the array in a wrong way like this:
pDC->MoveTo(someC[i]->a.x, someC->a.y)
So the second call was incorrect. Thank you all for your help
Philosophy aside, this is pretty telling from your comment (emphasis added):
"I am actually calling someC in OnDraw method like that: pDC->MoveTo(someC[i]->a.x, someC->a.y); someC is defined as public in the header file"
Specifically, this in your parameter list :
someC[i]->a.x, someC->a.y
This tells me one of these is wrong. Judging by your error, I'm going to go with the first one. It would solidify that if we could see the definition of your object that is implementing OnDraw() and where exactly it is getting someC from.
If someC is a C* in your containing object, the second parameter is correct, the first is wrong.
If someC is a C** in your contained object then the first parameter is correct and the second is wrong.
Unless your C objects are really really expensive to copy construct, don't bother implementing your custom sort algorithm, but define a strict total order over C:
bool operator<(C const& lhs, C const& rhs) {
return lhs.c1 < rhs.c1;
}
and use std::sort on an std::vector<C>. If you do worry about copy construction overhead, you can also directly use an std::set<C> which automatically sorts itself, without copy construction.
After your Edit: Your C seems relatively small and easy to copy, but it's borderline; Your best bet is to give both approaches (set and vector) and benchmark which one is faster.
If your type contains just a double I'd guess that it would be much faster not to use pointers! If the objects contain a std::string or a std::vector<T> (for some time T) the picture probably changes but compared to moving a structure with one or two basic objects, the cost of accessing more or less randomly distributed data is fairly high. Of course, to determine the specific situation you would need to profile both approaches.
I have a bit of a theoretical question, however it is a problem I sometimes face when designing classes and I see it done differently when reading others code. Which of the following would be better and why:
example 1:
class Color
{
public:
Color(float, float, float);
~Color();
friend bool operator==(Color& lhs, Color& rhs);
void multiply(Color);
// ...
float get_r();
float get_g();
float get_b();
private:
float color_values[3];
}
example 2:
class Color
{
public:
// as above
private:
float r;
float g;
float b;
}
Is there a general rule one should follow in cases like this or is it just up to a programmer and what seems to make more sense?
Both!
Use this:
class Color {
// ...
private:
union {
struct {
float r, g, b;
};
float c[3];
};
};
Then c[0] will be equivalent to r, et cetera.
It depends, do you intend to iterate over the whole array ?
In that case, I think solution 1 is more appropriate.
It is very useful to have an array like that when you have functions that operate in a loop on the data
e.g.
void BumpColors(float idx)
{
for (int i = 0; i < 3; ++i)
color_values[i] += idx;
}
vs
void BumpColors(float idx)
{
color_values[0] += idx;
color_values[1] += idx;
color_values[2] += idx;
}
Of course this is trivial, and I think it really is a matter of preference. In some rare occasion you might have APIs that take a pointer to the data though, and while you can do
awesomeAPI((float*)&r);
I would much prefer doing
awesomeAPI((float*)&color_values[0]);
because the array will guarantee its contiguity whereas you can mess up with the contiguity by adding by mistake another member variable that is not related after float r.
Performance wise there would be no difference.
I'd say the second one is the best one.
First, the data your variables contain isn't supposed (physically) to be in an array. If you had for example a class with 3 students, not more, not less, you'd put them in an array, cause they are an array of students, but here, it's just colors.
Second, Someone that reads your code also can understand in the second case really fast what your variables contain (r is red, etc). It isn't the case with an array.
Third, you'll have less bugs, you won't have to remember "oh, in my array, red is 0, g is 1, b is 2", and you won't replace by mistake
return color_values[0]
by
return color_values[1]
in your code.
I think that you are right: "It just up to a programmer and what seems to make more sense." If this were my program, I would choose one form or the other without worrying too much about it, then write some other parts of the program, then revisit the matter later.
One of the benefits of class-oriented design is that it makes internal implementation details of this kind private, which makes it convenient to alter them later.
I think that your question does matter, only I doubt that one can answer it well until one has written more code. In the abstract, there are only three elements, and the three have names -- red, green and blue -- so I think that you could go either way with this. If forced to choose, I choose example 2.
Is there a general rule one should follow in cases like this or is it just up to a programmer and what seems to make more sense?
It's definitely up to the programmer and whatever makes more sense.
In your case, the second option seems more appropriate. After all, logically thinking, your member isn't an array of values, but values for r, g and b.
Advantages of using an array:
Maintainability: You can use the values in the array to loop
Maintainability: When a value should be added (like yellow?) than you don't have to change a lot of code.
Disadvantage:
Readability: The 'values' have more clearer names (namely r, g, b in this case).
In your case probably the r, g, b variables are best, since it's unlikely a color is added and a loop over 3 elements has probably a less high importance than readability.
Sometimes a programmer will use an array ( or data structure )
in order to save the data faster to disk (or memory) using 1 write operation.
This is especially useful if you are reading and writing a lot of data.
I'm trying to get my head around tuples (thanks #litb), and the common suggestion for their use is for functions returning > 1 value.
This is something that I'd normally use a struct for , and I can't understand the advantages to tuples in this case - it seems an error-prone approach for the terminally lazy.
Borrowing an example, I'd use this
struct divide_result {
int quotient;
int remainder;
};
Using a tuple, you'd have
typedef boost::tuple<int, int> divide_result;
But without reading the code of the function you're calling (or the comments, if you're dumb enough to trust them) you have no idea which int is quotient and vice-versa. It seems rather like...
struct divide_result {
int results[2]; // 0 is quotient, 1 is remainder, I think
};
...which wouldn't fill me with confidence.
So, what are the advantages of tuples over structs that compensate for the ambiguity?
tuples
I think i agree with you that the issue with what position corresponds to what variable can introduce confusion. But i think there are two sides. One is the call-side and the other is the callee-side:
int remainder;
int quotient;
tie(quotient, remainder) = div(10, 3);
I think it's crystal clear what we got, but it can become confusing if you have to return more values at once. Once the caller's programmer has looked up the documentation of div, he will know what position is what, and can write effective code. As a rule of thumb, i would say not to return more than 4 values at once. For anything beyond, prefer a struct.
output parameters
Output parameters can be used too, of course:
int remainder;
int quotient;
div(10, 3, "ient, &remainder);
Now i think that illustrates how tuples are better than output parameters. We have mixed the input of div with its output, while not gaining any advantage. Worse, we leave the reader of that code in doubt on what could be the actual return value of div be. There are wonderful examples when output parameters are useful. In my opinion, you should use them only when you've got no other way, because the return value is already taken and can't be changed to either a tuple or struct. operator>> is a good example on where you use output parameters, because the return value is already reserved for the stream, so you can chain operator>> calls. If you've not to do with operators, and the context is not crystal clear, i recommend you to use pointers, to signal at the call side that the object is actually used as an output parameter, in addition to comments where appropriate.
returning a struct
The third option is to use a struct:
div_result d = div(10, 3);
I think that definitely wins the award for clearness. But note you have still to access the result within that struct, and the result is not "laid bare" on the table, as it was the case for the output parameters and the tuple used with tie.
I think a major point these days is to make everything as generic as possible. So, say you have got a function that can print out tuples. You can just do
cout << div(10, 3);
And have your result displayed. I think that tuples, on the other side, clearly win for their versatile nature. Doing that with div_result, you need to overload operator<<, or need to output each member separately.
Another option is to use a Boost Fusion map (code untested):
struct quotient;
struct remainder;
using boost::fusion::map;
using boost::fusion::pair;
typedef map<
pair< quotient, int >,
pair< remainder, int >
> div_result;
You can access the results relatively intuitively:
using boost::fusion::at_key;
res = div(x, y);
int q = at_key<quotient>(res);
int r = at_key<remainder>(res);
There are other advantages too, such as the ability to iterate over the fields of the map, etc etc. See the doco for more information.
With tuples, you can use tie, which is sometimes quite useful: std::tr1::tie (quotient, remainder) = do_division ();. This is not so easy with structs. Second, when using template code, it's sometimes easier to rely on pairs than to add yet another typedef for the struct type.
And if the types are different, then a pair/tuple is really no worse than a struct. Think for example pair<int, bool> readFromFile(), where the int is the number of bytes read and bool is whether the eof has been hit. Adding a struct in this case seems like overkill for me, especially as there is no ambiguity here.
Tuples are very useful in languages such as ML or Haskell.
In C++, their syntax makes them less elegant, but can be useful in the following situations:
you have a function that must return more than one argument, but the result is "local" to the caller and the callee; you don't want to define a structure just for this
you can use the tie function to do a very limited form of pattern matching "a la ML", which is more elegant than using a structure for the same purpose.
they come with predefined < operators, which can be a time saver.
I tend to use tuples in conjunction with typedefs to at least partially alleviate the 'nameless tuple' problem. For instance if I had a grid structure then:
//row is element 0 column is element 1
typedef boost::tuple<int,int> grid_index;
Then I use the named type as :
grid_index find(const grid& g, int value);
This is a somewhat contrived example but I think most of the time it hits a happy medium between readability, explicitness, and ease of use.
Or in your example:
//quotient is element 0 remainder is element 1
typedef boost:tuple<int,int> div_result;
div_result div(int dividend,int divisor);
One feature of tuples that you don't have with structs is in their initialization. Consider something like the following:
struct A
{
int a;
int b;
};
Unless you write a make_tuple equivalent or constructor then to use this structure as an input parameter you first have to create a temporary object:
void foo (A const & a)
{
// ...
}
void bar ()
{
A dummy = { 1, 2 };
foo (dummy);
}
Not too bad, however, take the case where maintenance adds a new member to our struct for whatever reason:
struct A
{
int a;
int b;
int c;
};
The rules of aggregate initialization actually mean that our code will continue to compile without change. We therefore have to search for all usages of this struct and updating them, without any help from the compiler.
Contrast this with a tuple:
typedef boost::tuple<int, int, int> Tuple;
enum {
A
, B
, C
};
void foo (Tuple const & p) {
}
void bar ()
{
foo (boost::make_tuple (1, 2)); // Compile error
}
The compiler cannot initailize "Tuple" with the result of make_tuple, and so generates the error that allows you to specify the correct values for the third parameter.
Finally, the other advantage of tuples is that they allow you to write code which iterates over each value. This is simply not possible using a struct.
void incrementValues (boost::tuples::null_type) {}
template <typename Tuple_>
void incrementValues (Tuple_ & tuple) {
// ...
++tuple.get_head ();
incrementValues (tuple.get_tail ());
}
Prevents your code being littered with many struct definitions. It's easier for the person writing the code, and for other using it when you just document what each element in the tuple is, rather than writing your own struct/making people look up the struct definition.
Tuples will be easier to write - no need to create a new struct for every function that returns something. Documentation about what goes where will go to the function documentation, which will be needed anyway. To use the function one will need to read the function documentation in any case and the tuple will be explained there.
I agree with you 100% Roddy.
To return multiple values from a method, you have several options other than tuples, which one is best depends on your case:
Creating a new struct. This is good when the multiple values you're returning are related, and it's appropriate to create a new abstraction. For example, I think "divide_result" is a good general abstraction, and passing this entity around makes your code much clearer than just passing a nameless tuple around. You could then create methods that operate on the this new type, convert it to other numeric types, etc.
Using "Out" parameters. Pass several parameters by reference, and return multiple values by assigning to the each out parameter. This is appropriate when your method returns several unrelated pieces of information. Creating a new struct in this case would be overkill, and with Out parameters you emphasize this point, plus each item gets the name it deserves.
Tuples are Evil.