Answer the question
In order to leave comments, you need to log in
How to pass class context to lambda?
C++14
For simplicity, I removed the extra from the class.
The fact is that the lambda does not change the test variable at all.
Even if I explicitly write this-> test
The debugger showed that this inside the lambda has a different address than the instance of the Protocol class itself.
How to be?
#pragma once
#include <serial.h>
class Protocol {
private:
Serial *serial;
bool test = false;
public:
Protocol (Serial &s) {
serial = &s;
serial->onInterrupt = [this]() {
test = true;
};
}
};
Answer the question
In order to leave comments, you need to log in
Drottarutarnum , p = { s };
is Copy Initialization .
Literally what's going on here. First you create a temporary local via the constructor Protocol::Protocol(Serial &s)
. Next, through operator =
, which boils down to a copy/move constructor, you do a Copy Construction of the object p
. This is done via the default copy/move constructor, which simply copies/moves fields using their copy/move constructors.
The lambda is created inside the temporary local value, because the corresponding constructor is called for it. Further, this lambda remains to live in the object Serial
, and the temporary local itself is destroyed immediately after construction p
.
After that, the dangling pointer to the already destroyed is left in the lambda closure this
.
One of the possible solutions to this problem may be not p = { s };
, but p{ s };
or, as you have already described, p = s;
. This type of initialization is already called Value Initialization . But in essence, this is only a delay of the problem. You will have to keep a very close eye on the life of such an object. the probability of finding the same dangling pointer in a closure as a result of implicit copying is extremely high.
Another possible solution to such a problem could be to use std::enable_shared_from_this
[ ? ], std::shared_ptr
[ ? ] to store the protocol and std::weak_ptr
[ ?] in the closure of your lambda. This method is guaranteed to solve your problem, but it can lead to a number of other problems with possible resource leaks.
Another way is to teach how to Serial
unhook the lambda of the destroyed Protocol
one and write the correct copy constructor Protocol
, observing the 3/5/0 rule .
In a general sense, you should be more careful about what operations you perform on objects, the raw pointer to which you want to store somewhere.
To prevent this from happening again in the future, you need to remove the copy/move constructors and the copy/move operators from Protocol
. This class really should be non-movable, because its address is stored in a lambda, which is hard to control.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question