Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am starting to be more and more attracted to writing long C++ algorithmic functions using successive scoped blocks, as follows:
void my_algorithm(const MyStruct1 &iparam1, MyStruct2 &oparam2)
{
// First block
MyStruct3 intermediate_var3;
{
double temporary_var;
// Functional step 1.1
// Functional step 1.2
intermediate_var3 = ...
}
// Second block
MyStruct4 intermediate_var4;
{
double temporary_var;
// Functional step 2.1
// Functional step 2.2
intermediate_var4 = ...
}
// Final block
{
int temporary_var;
oparam2 = ...
}
}
I am starting to think it is a good way to clarify the function structure and to limit the scope of temporary variables (such as counters i, j, k etc). I saw that such scope blocks make sense in C functions to enable new declarations (see Why enclose blocks of C code in curly braces?).
In the context of C++, is this good or bad practice ?
This is a clear sign, that you should extract this separate blocks into separate functions.
MyStruct3 DoSth3(params)
{
double temporary_var;
// Functional step 1.1
// Functional step 1.2
return ...
}
MyStruct4 DoSth4(params)
{
double temporary_var;
// Functional step 2.1
// Functional step 2.2
intermediate_var4 = ...
}
void my_algorithm(const MyStruct1 &iparam1, MyStruct2 &oparam2)
{
// First block
MyStruct3 intermediate_var3 = DoSth3(params);
// Second block
MyStruct4 intermediate_var4 = DoSth4(params);
int temporary_var;
oparam2 = ...
}
It may happen, that you'll be worried about DoSth3 and DoSth4 being public, as they should be private in the context of my_algorithm. In such case you can solve it in the following way:
class my_algorithm
{
private:
static MyStruct3 DoSth3(params);
static MyStruct4 DoSth4(params);
public:
static void Perform(const MyStruct1 &iparam1, MyStruct2 &oparam2);
};
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have been asked several times about the uses of static object and I guess I understand the crux behind using them, but one particular case confusing me, I know that in the code they are trying to make a factorial like mechanism using recursive call but did not able to understand different stages the code will go through.
#include<iostream>
using namespace std;
template<short N> class C
{
private:
static C<N-1>c;
public:
static int const n = N*c.n;
};
template<> class C<0>
{
public:
static int const n =1;
};
int main()
{
cout<<C<5>::n<<endl;
return 0;
}
See the live demo here please.
This code is generating an output 120.
What exactly is happening here?
It's unfortunate that the line
static C<N-1>c;
exists at all. It obfuscates the logic a little bit.
The functionality could have been as easily implemented as:
template<short N> class C
{
public:
static int const n = N*C<N-1>::n;
};
template<> class C<0>
{
public:
static int const n = 1;
};
which is a little bit easier to follow.
The net effect is same:
C<5>::n = 5*C<4>::n
C<4>::n = 4*C<3>::n
C<3>::n = 3*C<2>::n
C<2>::n = 2*C<1>::n
C<1>::n = 1*C<0>::n
C<0>::n = 1
Now you can follow how the program produces the output.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
What options are available to create an object with lots of parameters in the global namespace? I'm thinking of the tradeoff between temporary object/variable creation and readability.
Edit
This is for embedded programming on the Arduino. It will be the main object of a reusable library controlling a set of nested objects.
Background: I have a test PCB which can be populated differently depending on its final use and I need to cover all of these options in one easy to use library. I am trying to avoid the user accidently missing required initialisation parameters before using the object.
Feel free to constructively criticise my code!
The two options that I can think of are:
A constructor with lots of parameters.
A constructor with a single struct parameter.
Option 1 looks messy and hard to follow with lots of parameters.
Option 2 requires a temporary struct variable for readability.
Example below (normally I would separate into headers etc.):
#include <Arduino.h>
class NestedClass {
public:
// Empty constructor for creation of unitialised object. Bad practice?
NestedClass() {
}
// Main constructor.
NestedClass(float voltageReference) :
voltageReference_(voltageReference) { // Use initialisation list.
}
float measureVoltage(uint_fast8_t channel) {
// Convert ADC value to absolute voltage.
return analogRead(channel) * (voltageReference_ / 1023);
}
private:
float voltageReference_;
};
class ComplexClass {
public:
enum class Mode
: uint_fast8_t {
MODE1,
MODE2,
MODE3
};
struct Parameters {
uint_fast8_t parameter1;
uint8_t parameter2;
float parameter3;
float parameter4;
Mode mode;
float voltageReference;
};
// Empty constructor for creation of unitialised object. Bad practice?
ComplexClass(void) {
}
// Big constructor. Messy when used.
ComplexClass(uint_fast8_t parameter1, uint8_t parameter2, float parameter3,
float parameter4, Mode mode, float voltageReference) {
// Could have used initialisation list instead.
this->parameter1_ = parameter1;
this->parameter2_ = parameter2;
this->parameter3_ = parameter3;
this->parameter4_ = parameter4;
this->mode_ = mode;
this->nestedClass_ = NestedClass(voltageReference); // Wasted temporary object with reassignment?
}
// Alternative constructor. Looks neater/more legible when used.
ComplexClass(Parameters parameters) {
this->parameter1_ = parameters.parameter1;
this->parameter2_ = parameters.parameter2;
this->parameter3_ = parameters.parameter3;
this->parameter4_ = parameters.parameter4;
this->mode_ = parameters.mode;
this->nestedClass_ = NestedClass(parameters.voltageReference); // Wasted temporary object with reassignment?
}
void megaMeasurements() {
// Do something involving nestedClass.measureVoltage().
}
private:
// Maybe put all of these in another struct for neatness?
uint_fast8_t parameter1_;
uint8_t parameter2_;
float parameter3_;
float parameter4_;
Mode mode_;
NestedClass nestedClass_;
};
//####################
// Start main code.
//####################
// Option 1:
// Not immediately obvious which value is for which parameter.
ComplexClass complexClass(1, 2, 3.30, 2.7, ComplexClass::Mode::MODE2, 5.00);
// Option 2:
// Unitialised object (sort-of).
ComplexClass complexClass2;
// Arduino standard function. Called once from main.cpp
void setup() {
// Option 2 continued:
ComplexClass::Parameters parameters;
parameters.mode = ComplexClass::Mode::MODE2;
parameters.parameter1 = 1;
parameters.parameter2 = 2;
parameters.parameter3 = 3.30;
parameters.parameter4 = 2.7;
parameters.voltageReference = 5.00;
complexClass2 = ComplexClass(parameters); // Reassignment. Wasteful?
}
// Arduino standard function. Called in a continuous loop after setup().
void loop() {
complexClass.megaMeasurements();
complexClass2.megaMeasurements();
}
My opinion (based on my practice):
constructor with many parameters look messy and should better be avoided. More, if some parameters are bad, you can't return "false" and the only way to complain is to throw an exception. If you want to go this way, it's better to define some init() function with several parameters, optionally returning false (or some error code) to complain if parameters are bad. In this case it's better to avoid literal numeric values using #define or static const declarations.
The other way is to assign values one by one, either directly (public) or with set() methods. In this case you can put literals in the code.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have a question that is sort of a follow up to this:
Initializing default values in a struct
I've got a struct that's already got 17 bools, and a clear() method that sets them all to false. It's a long term project; the code could still be in use years from now and get added to. Is there a way to initialize all members that will extend automatically, so that someone adding new members to the struct doesn't need to remember to add them to the clear() method (other than a comment saying "please don't forget")?
This code base is not C++11 at this time, so I don't think I can initialize in the declaration.
The code is like this:
typedef struct {
bool doThingA;
bool doThingB;
bool doThingC;
bool doThingD;
// etc for several more bools
void clear() {
doThingA = false;
doThingB = false;
doThingC = false;
doThingD = false;
// etc...
}
} EnableFlags;
struct EnableFlags {
bool doThingA;
bool doThingB;
bool doThingC;
bool doThingD;
// etc for several more bools
void clear() {
*this = EnableFlags();
}
};
This will create a temporary with all members set to zero and then make *this a copy of it. So it sets all the members to zero, no matter how many there are.
This assumes that you haven't defined a default constructor that does something other than set all the flags to false. If you have no user-defined constructors then that assumption holds.
Since C++11 it's even simpler:
void clear() {
*this = {};
}
One option is to use a static assertion about the size of the structure inside the clear function.
First determine the current size of the struct. Let's say it's 68. Then, add this:
void clear()
{
BOOST_STATIC_ASSERT(sizeof(EnableFlags) == 68 && "You seem to have added a data member. Clear it before changing the number 68 to match current struct size!!");
// the rest as before ...
}
I've used Boost's static assertion macro, but you can use any other one you want, or roll out your own.
With such an assertion, the code will fail to compile when the size of the structure changes. It's not a catch-all solution, but does provide a safeguard.
Just use objetcs.
So you can use a 'for' loop to check in a std::vector if their values are false or true.
So you don't have your futurs co-workers put the "false" value each time they create a new boolean variable.
Structures are inapropriates here.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How to use 'reference variables' in C++ classes?
I have the following code that I want to put into a class: (note KinectCV&)
KinectCV& kinect = freenect.createDevice(0);
kinect.some_init_functions();
while(condition) {
// getting frames from kinect and processing
kinect.some_processing_functions();
}
kinect.some_stopping_functions();
I'm trying to make a class and separate init, process and stop functions:
class MyKinect {
public:
KinectCV kinect;
void init(){
/* I cannot use the '& kinect = freenect.createDevice(0);' syntax, help me in this */
}
void process(){
kinect.some_processing_functions();
}
void stop(){
kinect.some_stopping_functions();
}
}
I cannot use the '& kinect = freenect.createDevice(0)
That is right, you cannot assign references; once initialized, they refer to the same object forever. What looks like an assignment in your code that works
KinectCV& kinect = freenect.createDevice(0);
is not an assignment, it's initialization. It can be rewritten using the initialization syntax instead of the assignment syntax, like this:
KinectCV& kinect(freenect.createDevice(0));
The reason behind it is that in C++ all initialization must happen in the constructor, not in a "designated initialization function". C++ has no idea that init is your initialization function; all it knows is that once the constructor is over, the object must be in a consistent state, included with all the references that it might hold.
Moving the initialization code into MyKinect's constructor will fix the problem:
class MyKinect {
public:
KinectCV kinect;
MyKinect() : kinect(freenect.createDevice(0)) {
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
An example using the Conditional Operator.
void setSelected( bool selected )
{
a = selected? SELECTED_VALUE_A: DEFAULT_VALUE_A;
b = selected? SELECTED_VALUE_B: DEFAULT_VALUE_B;
c = selected? SELECTED_VALUE_C: DEFAULT_VALUE_C;
}
An example using an if and temporaries.
void setSelected( bool selected )
{
a = DEFAULT_VALUE_A;
b = DEFAULT_VALUE_B;
c = DEFAULT_VALUE_C;
if ( selected )
{
a = SELECTED_VALUE_A;
b = SELECTED_VALUE_B;
c = SELECTED_VALUE_C;
}
}
An example using functions
void setLook( int nA, float nB, std::string nC )
{
a = nA;
b = nB;
c = nC;
}
void setSelected( bool selected )
{
if ( selected )
setLook( DEFAULT_VALUE_A, DEFAULT_VALUE_B, DEFAULT_VALUE_C );
else
setLook( SELECTED_VALUE_A, SELECTED_VALUE_B, SELECTED_VALUE_C );
}
An alternate example using functions. Still uses setLook
void setLookSelected()
{
setLook( SELECTED_VALUE_A, SELECTED_VALUE_B, SELECTED_VALUE_C );
}
void setLookNormal()
{
setLook( DEFAULT_VALUE_A, DEFAULT_VALUE_B, DEFAULT_VALUE_C );
}
void setSelectedAF( bool selected )
{
if ( selected )
setLookSelected();
else
setLookNormal();
}
//Or just call
setLookSelected();
setLookNormal();
Let's simplify the requirement:
Set variable a to c if b is true or d otherwise
Using the conditional operator:
a = b ? c : d;
IMHO, as clear as it can get
Using temporaries and if:
a = c;
if (b)
a = d;
Really ugly. You assign c to a, even if !b. Besides the awful readability, you encounter performance drop, as you have a double assignment. The optimizer could take care of that, but don't count on it.
Using functions:
void setA(T x)
{
a = x;
}
//....
if (b)
setA(c);
else
setA(d);
This could be useful if you have a lot of members that you want to set. Code maintenability will be improved. You'd only need to change in one place if you want different functionality. Not bad!
Alternate functions:
void setAC()
{
a = c;
}
void setAD()
{
a = d;
}
//...
if (b)
setAC();
else
setAD();
Another option I'd advise against. What if you don't want to check only for b in the future? What if the two variants aren't exclusive, i.e. you want to combine ID_NODE_GLOW_SELECT with ID_NODE_COLOR_NORMAL for some other condition?
Conclusion: I'd use the first variant for simple, small cases, and the functions with parameters for large classes, where you set a lot of members. I'd definetely stay away from options 2 & 4.
If the answer isn't clean and obvious, sometimes it means you're asking the wrong question.
Scanning your code, I suspect there are two design changes that would be a good idea:
Collect all of the style data into a single sprite_style class. This way, you can make some named constants for each of the various styles, and then you can change the style with one simple set_style function call.
Move the selection code out of the sprite class -- let the sprite class be just the basic stuff you need for a sprite. Move this style switching stuff into a subclass, or even better, into an event handler that's triggered upon state change.