Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
5 years, 2 months ago.
Initialization of NonCopyable object as a local variable in a class object
Hello Everyone,
I'm trying to get clear with RTOS functionality of MBED. Now I'm working with EventFlags class. I'm going to use this que-based object for tansport of events between my classes. For example, button pressed and whatever.
The problems is I don't know how to initialize a local variable in my own class. Let me explain:
main.cpp
EventFlags event_flags; // Init EventFlags AVModule AVM=AVModule(); // Init my class Thread tAVM; // Init thread for AVM int main(){ AVM.Init(event_flags); // Transfer EventFlags object to my object tAVM.start(callback(&AVM, &AVModule::Dispatcher)); //Assign a method of my class to the thread while(1){ // Main loop HAL_Delay(10000); // Just a pause event_flags.set(1); // Drop a flag #1 to the que } }
AVModule.cpp
AVModule::AVModule() { // Constructor of my object } AVModule::Init(EventFlags &ef){ EventFlags &_ef=ef; } void AVModule::Dispatcher(){ uint32_t flags_read = 0; flags_read = _ef.wait_any(); // waiting for an event }
AVModule.h
public: void Dispatcher(); void Init(EventFlags &ef); private: EventFlags _ef;
So the question is how to init intra-class EventFlags variable that can be accessed by any of class members?
Currently I get tow error messages: 1. AVModule AVM=AVModule(); note: copy constructor of 'AVModule' is implicitly deleted because field '_ef' has a deleted copy constructor. That refers to main.cpp 2. EventFlags _ef; note: copy constructor of 'EventFlags' is implicitly deleted because base class 'mbed::NonCopyable<EventFlags>' has an inaccessible copy constructor class EventFlags : private mbed::NonCopyable<EventFlags> (that refers to AVModule.h)
1 Answer
5 years, 2 months ago.
Hello Vladislav,
The EventFlags
class is an ancestor of the NonCopyable
class. That was introduced in Mbed to prevent generation of copy constructor and copy assignment operator in order to prevent subtle bugs that are difficult to debug. So to avoid copying an instance of the EventFlags
class like
_ef = ef;
which would call EventFlags
's copy constructor, you have the following options:
- Either declare the
_ef
data member as anEventFlags
reference and initialize it in the constructor:
AVModule.h
class AVModule { EventFlags& _ef; //... public: AVModule(EventFlags& ef) : _ef(ef) { } //... };
main.cpp
EventFlags event_flags; AVModule AVM(event_flags); // Creates in initializes the AVM object int main() { //... }
- or declare the
_ef
data member as pointer toEventFlags
and initialize it in the constructor:
AVModule.h
class AVModule { EventFlags* _ef; //... public: AVModule(EventFlags* ef) : _ef(ef) { } //... };
main.cpp
EventFlags event_flags; AVModule AVM(&event_flags); // Creates in initializes the AVM object int main() { //... }
- or declare the
_ef
data member as pointer toEventFlags
and initialize it by calling aninit
method:
AVModule.h
class AVModule { EventFlags* _ef; //... public: AVModule() { } void init(EventFlags* ef) { _ef = ef; } // Assignes pointer to pointer. No copy constructor is called. //... };
main.cpp
EventFlags event_flags; AVModule AVM; // Creates the AVM object. int main() { AVM.init(&event_flags); // Initializes the AVM object. //... }
I noticed that you have tried to "declare + define" an AVModule
object like:
AVModule AVM=AVModule(); // Init my class
Such code first creates a temporary AVModule
object (when AVModule()
is called). Then creates another AVModule
object with name AVM
by calling AVModule
's default constructor. And finally assigns the temporary AVModule
object to the AVM
object by calling AVModule
's copy constructor.
It's simpler and more efficient to do it like:
AVModule AVM; // Creates in initializes the AVM object.