4

以下のこのコードの問題点とその修正方法。

#include<iostream>
using namespace std;

template<typename Func1, typename Func2>
class guard{
public:
    guard(Func1 first, Func2 last) : last(last){
        first();
    }
    ~guard(){
        last();
    }
private:
    Func2& last;
};

template<typename Func1, typename Func2>
guard<Func1, Func2> make_guard(Func1 first, Func2 last){
    return guard<Func1, Func2>(first, last);
}

void first(){
    cout << "first" << endl;
}

void last(){
    cout << "last" << endl;
}

int main(){
    {
        first(); // ok
        last(); // ok
        auto g = make_guard(first, last);
        first(); //exception: Access violation
        last(); //exception: Access violation
    }
    first(); // ok
    last(); // ok
    cin.get();
}

関数はfirst()last()変数の有効期限が切れる前に呼び出すことはできませんg。VC++ 2012 でコンパイルされ、デバッグ モードとリリース モードの両方で同じ問題が発生しました。

4

1 に答える 1

5

あなたは参照guardを保持しますが、を取ります。に渡されたパラメーターではなく、コンストラクターによって取得されたパラメーターを参照するため、参照はのコンストラクターが終了するとすぐに無効になります。guardlastmake_guard

無効な参照にアクセスすると、未定義の動作が発生し、すべての賭けが無効になります。

于 2012-12-22T04:36:19.623 に答える