5

例でよりよく説明します:

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

プログラムは間違っている 0 を出力します。実際のコードでは、セグ フォールトが発生します。

ここでは、const 参照に割り当てられた temp の寿命を延ばすという規則が成り立つと思いますが、明らかにそうではありません。その理由を知っていますか?

4

1 に答える 1

4

その規則は、クラス メンバーには適用されません。これは、C++03 標準の 12.2.5 に記載されています。

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

一時的なものをそれよりも長くすることは、その寿命を維持できるように、一時的なものをクラスの一部として保持する必要があることを意味します。クラスが定義されているときにクラスのサイズを知る必要があるため、コンストラクターが別のコンパイル単位にある場合、これは不可能です。

// 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.
{
}
于 2012-07-07T16:11:05.363 に答える