Почему передача себя по ссылке приводит к ошибке неверного доступа?

0

Следующий фрагмент кода работает нормально. Я зарегистрировать Objective-C функцию mytestslot в качестве обратного вызова для сигнала, исходящего в C++ класс thing. Функция слота вызывается периодически, и все хорошо себя ведет.

struct CPPMembers { // pimpl related stuff for C++ members
    Thing thing;
    boost::signals2::scoped_connection con;
};

@implementation MyChannelClass

-(void)mytestslot:(float)num{
    NSLog(@"Slot call = %0.2f", num);
}

-(id)init
{
    self = [super init];
    if (self) {
        //Allocate storage for C++ members
        _cppMembers = new CPPMembers;

        auto slotLambda = [self](float n){[self mytestslot:n];};
        _cppMembers->con =  _cppMembers->thing.addSubscriber(  slotLambda   );
    }


    return self;
}
...

Однако, когда я меняю slotLambda на захват по ссылке. ,

auto slotLambda = [&](float n){[self mytestslot:n];};

Я получаю EXC_BAD_ACCESS во время выполнения, когда сигнал запускается. Я предполагаю, что это может быть связано с фундаментальным различием между Objective-C self и C++ this, что я не хватать, но я не совсем уверен, как я в общей сложности Objective-C Newby!

Теги:
c++11
lambda
signals

2 ответа

1
Лучший ответ

Поскольку ссылка является указателем на переменную, замаскированную под поведение, синтаксически подобную самой переменной.

Каков адрес self? в архитектуре x86 это будет параметр в стеке. На руке и x64 это будет регистр. В любом случае, как только -init после -init, ссылка будет ссылаться на мусор.

  • 0
    Спасибо, так что же такое self ? Тяжело ли переходить по значению, если сам класс становится более тяжелым, или self просто некая ссылка?
  • 0
    @learnvst: self - это локальная переменная (это параметр) в методах. В любом случае в лямбдах могут быть записаны только локальные переменные.
Показать ещё 2 комментария
0

Этот вопрос не обязательно связан с self или с Objective-C.

В C++ не имеет смысла брать лямбду, которая захватывает переменные по ссылке и сохраняет ее так, чтобы лямбда (или ее копия) переживала функцию, в которой она была создана.

Это связано с тем, что переменные, захваченные lambdas (либо по значению, либо по ссылке), должны иметь продолжительность автоматического хранения (то есть локальные переменные), а неопределенное поведение в C++ для доступа к ссылке после того, как переменная, на которую указывает указывает, выходит за пределы области,

Ещё вопросы

Сообщество Overcoder
Наверх
Меню