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.
6 years, 1 month 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
6 years, 1 month 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
_efdata member as anEventFlagsreference 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
_efdata member as pointer toEventFlagsand 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
_efdata member as pointer toEventFlagsand initialize it by calling aninitmethod:
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.