0
template<typename T>
class RAII
{
public:

    explicit RAII( T* p = 0 ): p_(p){}

    ~RAII() {delete p_;}

    T& operator*() const { return p_;} 
    T* operator‐&gt;() const{ return p_;}
};

//Usage example:
{
      RAII<std::vector<int>> r(new std::vector<int>());
      std::cout<<r­‐&gt;size()<<std::endl;
} // The std::vector<int> is automatically deallocated

こんにちは、みんな :)

私の質問: この特定のケースでの明示的なコンストラクターと 2 つの演算子のオーバーロードの目的は何ですか?また、使用例ではどのように使用されていますか?

前もって感謝します。

4

1 に答える 1

0

まず、2 つのエラーがあります。p_ が宣言されていないことと、戻り値が でoperator*あることreturn *p_です。


とにかく、明示的であるため、コンストラクターを暗黙的に呼び出すことはできません。

このことを考慮:

class Example {
public:
    int x;
    Example(int x) : x(x) {}
};

function ex(const Example& e) {
    std::cout << e.x;
}

int main() {
    ex(5);
    return 0;
}

これがコンパイルされると思いますか?します。そして、それは 5 を出力します。その理由は、Example が暗黙的に構築されるためです。基本的にex(5)は静かに に変わりex(Example(5))ます。コンストラクターを明示的にマークすると、この動作が禁止されます。コンストラクターに明示的に追加した場合、これはコンパイル時エラーになります。


演算子のオーバーロードに関しては、ここにあるのは基本的な「スマート」ポインターです。(ちなみに、標準化されたコンパイラを使用できない場合は、おそらくC++ 11またはブーストの標準のものの1つを使用します。)

演算子のオーバーロードにより、オブジェクトは特定の方法でオブジェクトに反応できます。この状況では、演算子のオーバーロードにより、クラスが含まれているのと同じ型へのポインターであるふりをすることができます。

RAII<std::vector<int>> r(new std::vector<int>());
std::cout<<r­‐&gt;size()<<std::endl;

rstd::vector<int>*ここでオーバーロードしている via 演算子のふりをしています。実際に起こっているのは、次のように呼び出されていることです。

(r­.operator->())->size()

operator->を返すstd::vector<int>*ので、2番目->はそれにアクセスしてsize()メソッドを呼び出しています。

おそらくよく知られている演算子のオーバーロードの別の例は、 std::vectoroperator[]です。 operator[]要素への参照を返します。

もちろん、演算子のオーバーロードは、既に組み込まれていることを行うふりをするために常に使用されるわけではありません。を考慮してくださいostreamoperator<<ビットシフト演算子ではなく、データをストリームに入れます。


詳細:標準スマート ポインター/ブースト スマート ポインター/ RAII /演算子のオーバーロード

ああ、あなたのコードは、非常に一般的に守られている3 の規則(またはC++11 の 5 の規則) に違反しています。そのままでは、コピーが作成されると、クラスはポインターを二重に削除します。

RAII<int> p(new int)
RAII<int> q = p;
//when q's destructor runs, bad bad things will happen since p's destructor already deleted the int.
于 2013-01-09T08:51:28.163 に答える