2016-06-19 35 views
6

Ho trovato un problema molto strano con questo puntatore in lambda di C++ 11.'questo' puntatore cambia in C++ 11 lambda

#include <string> 
#include <iostream> 
using namespace std; 

#include <boost/signals2.hpp> 

boost::signals2::signal<void()> sig; 

struct out { 
    void print_something() { 
     cout << "something" << endl; 
    } 
    out() { 
     auto start = [&] { 
      cout << "this in start: " << this << endl; 
      this->print_something(); 
     }; 

     cout << "this in constructor: " << this << endl; 

     // sig.connect(start); 
     sig.connect([&] { 
      cout << "this in signal: " << this << endl; 
      start(); 
     }); 
     this->print_something(); 
    } 
}; 

int main() { 
    out o; 
    sig(); 
} 

Il codice stampa tre questo puntatore in un'altra posizione. Mi aspettavo che tutti e tre questo puntatore dovessero avere lo stesso valore, ma non lo sono. Ecco l'output:

this in constructor: 00F3FABB 
something 
this in signal: 00F3FABB 
this in start: 00F3FB00 
something 

Domanda 1: Perché è this in start ha valore diverso? Come correggerlo?

Domanda 2: Dal momento che il this in start è un puntatore diverso, non dovrebbe essere in grado di chiamare print_something(). Mi aspetterei un incidente su questo, ma funziona bene. Perché?

+0

Si sta acquisendo questo puntatore tramite il riferimento – JustSid

+2

@JustSid: "questo" è [sempre catturato dal valore] (https://stackoverflow.com/q/16323032/56338), anche con '[&]'. – sth

+0

@sth Ha! Più sai, grazie :) – JustSid

risposta

5

Si acquisisce start come riferimento, ma la variabile start e la funzione lambda contenuta vengono distrutte alla fine di out().

Successivamente il gestore di segnale tenta di chiamare start(), ma la funzione lambda non esiste più. Forse la memoria in cui è stato memorizzato il suo this è stata sovrascritta nel frattempo, causando un risultato inaspettato.

La chiamata a print_something() non si arresta in modo anomalo nonostante l'invalido this poiché la funzione in realtà non tenta di utilizzare this. La stampa nella funzione è indipendente da this e la ricerca dell'indirizzo print_something s può avvenire in fase di compilazione in modo che la chiamata alla funzione non acceda a this in fase di esecuzione.