2012-07-07 16 views
5

meglio spiegato con un esempio:assegnando una temperatura di un membro ref const causa un errore di segmentazione

tok.h

#include <string> 

static const char* defaultDelim = ".,;"; 

class Tokenizer { 
public: 
    Tokenizer(): 
     // 'delim' is the const ref member that is initialized by the temp string 
     delim((altDelim.size())? altDelim : std::string(defaultDelim)) 
    {} 

    size_t scan(const std::string& str) 
    { return str.find_first_of(delim); } 

    static void setDelim(const std::string& d) { altDelim = d; } 
private: 
    static std::string altDelim; 
    const std::string& delim; 
}; 

main.cpp

#include <iostream> 
using namespace std; 

#include "tok.h" 

std::string Tokenizer::altDelim; 

int main() 
{ 
    Tokenizer tok; 

    size_t pos = tok.scan("hello, world"); 
    cout << pos << endl; 
} 

la il programma stampa 0 che è sbagliato. Il codice reale ha un difetto di seg.

Mi aspetterei che la regola di prolungare la durata di una temperatura assegnata a un riferimento const rimanga qui, ma a quanto pare non lo è. Conosci la ragione?

risposta

4

Questa regola non si applica ai membri della classe. Ciò viene affermato nel 12.2.5 del C++ 03 di serie:

A temporary bound to a reference member in a constructor's ctor-initializer 
persists until the constructor exits. 

Rendere l'ultimo temporanea più lungo di quello implicherebbe che la temporanea avrebbe dovuto essere tenuto come parte della classe in modo che la sua vita potrebbe essere mantenuto. Ciò sarebbe impossibile se il costruttore si trovasse in un'unità di compilazione separata, poiché la dimensione della classe deve essere nota al momento della definizione della classe.

// header file 
struct A { 
    A(); 
    B &b; 
}; 


// file1.cpp 
void f() 
{ 
    A a; // Reserve the size of a single reference on the stack. 
} 


// file2.cpp 
A::A() 
: b(B()) // b is referencing a temporary, but where do we keep it? 
     // can't keep the temporary on the stack because the 
     // constructor will return and pop everything off the stack. 
     // Can't keep it in the class because we've already said the 
     // class just contains a single reference. 
{ 
} 
+0

Spot on, non vedo perché non ci sono stati upvotes per questo. Giornata lenta oggi :( –

+0

conciso e completo, grazie mille! – davka