2012-07-07 21 views
5

giải thích tốt hơn bằng một ví dụ:gán tạm thời cho một thành viên ref const gây ra một lỗi segmentation

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; 
} 

sự chương trình in 0 là sai. Mã thực sự bị lỗi seg.

Tôi mong rằng quy tắc kéo dài tuổi thọ của một temp được gán cho tham chiếu const sẽ giữ ở đây, nhưng có vẻ như không. Bạn có biết lý do không'?

Trả lời

4

Quy tắc đó không áp dụng cho thành viên của lớp học. Điều này được nêu trong 12.2.5 của tiêu chuẩn C++ 03:

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

Làm còn là tạm thời qua hơn mà có ngụ ý rằng tạm thời sẽ phải được giữ như là một phần của lớp để đời của nó có thể là được duy trì. Điều này sẽ là không thể nếu các nhà xây dựng được trong một đơn vị biên dịch riêng biệt, bởi vì kích thước của lớp phải được biết khi lớp được xác định.

// 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

Phát hiện, tôi không thấy lý do tại sao không có upvotes cho việc này. Chậm ngày hôm nay. :( –

+0

ngắn gọn và toàn diện. Cảm ơn rất nhiều! – davka

Các vấn đề liên quan