use a class in multiple others

I'm rewriting some STM32 C code to C++ and stumbled upon an issue.

I used to have a delay(x) function, which obviously offered a delay.
This was used all over the code.
I now have a new class for this (shortened version):

class delayclass {
delay(TIM_TypeDef *timer);
void us(uint32_t t);
void ms(uint32_t t);
};

It's instantiated at system startup with, for example:
delayclass delayinstance(TIM6);

How would be the best way to enable other classes to use this?
In C it was simple, just call delay(x) (assuming a suitable declaration in a header file or simiar).
I _could_ of course just call to the global delayinstance.us(x) from any class, but that would be rather dirty, I think.
Passing it to every single class that needs to use it, also feels a bit over the top.
There must be more elegant ways to do this.

Suggestions?
Last edited on
Why not create a new instance everywhere you need it? When you leave scope, the instance is destroyed/

I guess I just don't understand why you only want one of these.
In C it was simple
C++ is 99% backwards compatible with C, so worse case is you just mostly leave it alone, no? Guess I don't really understand what broke here.

If your class has no data members, in my opinion there's no point in making it a class. Just make it a namespace.
Last edited on
If there is more than once instance (say, with different timers), this is one way:

in the header delay_class.h
1
2
3
4
5
6
7
8
9
class delay_class
{
    // ....
};

// declaration of the delay objects (a la declaration of std::cout etc. in <iostream>)
extern delay_class delay_tim6 ;
extern delay_class delay_tim11 ;
// etc. 


in delay_class.cpp
1
2
3
4
// definition of the delay objects
delay_class delay_tim6(TIM6);
delay_class delay_tim11(TIM11);
// etc. 


Note: with this approach, we need to make sure that there is no potential static initialization order fiasco
https://isocpp.org/wiki/faq/ctors#static-init-order

Or address it if it exists
with the construct on first use idiom https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
or the nifty counter idiom https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter
one of the KEY features of C++ that I love most is that you do not need a class for everything. You can still write a function and just use it. Objects when not necessary should be avoided.

C++ also has a powerful <chrono> library (its part of the language like iostream etc) that can help with a busy-wait delay. It also has the simpler tools like various flavors of sleep (crude, but often sufficient).

I don't think you want or need a class for a delay, unless you are doing much more than just a delay, in other words. I believe at worse you could make a wrapper function for one of the C++ tools to avoid rewriting what you had, making it look the same as before; it could be that a typedef/using statement is sufficient here so its not even a full wrapper just a rename.
Last edited on
Thank you everyone for all your replies.
I guess the most relevant reply was "Why not just keep it as it was, in C". ;)
I'm not aware of what a namespace would offer, I'll have a look at that.

My example was just very small and stripped, there will be more to this later and that's one of the reasons for a class.

Instantiation would be ok, right now, as it's just used for a blocking delay, but there will also timeouts and other functionality which will prohibit that.

Static initialization and setting the timer reference is fine with this class, but in general, with the HW involved, classes would need to have a init function or similar, as many things are not "ready" until some special HW initialization code has been run.

I ended up with, for now, with what I understand is called a singleton approach:

The delay class have a static function that returns the statically defined instance:

static delay* getInstance() { return &delayInstance; }

And classes that needs to use delay, call this or simply use:

delay::getInstance()->ms(1000)

Works for now.








Topic archived. No new replies allowed.