4

私は次のコードを見ました、

#include <new>
#include <memory>
using namespace std;

class Fred;  // Forward declaration
typedef  auto_ptr<Fred>  FredPtr;

class Fred {
public:
  static FredPtr create(int i)
  { 
    return new Fred(i); // Is there an implicit casting here? If not, how can we return
                        // a Fred* with return value as FredPtr?
  }
private:
  Fred(int i=10)      : i_(i)    { }
  Fred(const Fred& x) : i_(x.i_) { }
  int i_;
};

関数作成にリストされている質問を参照してください。

ありがとうございました

//コメントに基づいて更新

はい、コードはVC8.0エラーC2664を渡すことができません:'std :: auto_ptr <_Ty> :: auto_ptr(std :: auto_ptr <_Ty>&)throw()':パラメーター1を'Fred*'から'に変換できませんstd :: auto_ptr <_Ty>& '

コードはC++FAQ12.15からコピーされました。

ただし、以下の変更を行った後、

replace 
  return new Fred(i);
with
  return auto_ptr<Fred>(new Fred(i));

このコードはVC8.0コンパイラを渡すことができます。しかし、これが正しい修正であるかどうかはわかりません。

4

3 に答える 3

6

std::auto_ptr引数としてrawポインターを受け取るコンストラクターがexplicitありますが、そのコンストラクターは変換コンストラクターとして使用できます。

このコードはコンパイルされません。

于 2011-01-01T22:21:16.430 に答える
3

いいえ、そのような暗黙の変換は存在しません。ただし、これは実際には良いことであることがわかります。たとえば、次のコードを検討してください。

void MyFunction(const std::auto_ptr<Fred>& myFred) {
   /* ... do something to Fred. */
}

int main() {
    Fred* f = new Fred;
    MyFunction(f); // Not legal, but assume it is.
    f->doSomething();
}

ここで、Fred への生のポインターを MyFunction に渡すことができれば、その関数が戻り、一時的な auto_ptr オブジェクトがクリーンアップされると、main() で割り当てたメモリが回収され、f->doSomething( への呼び出し) は、おそらくセグメンテーション違反を引き起こします。auto_ptr コンストラクターを明示的にすることは、これに対する安全策です。他の誰かがリソースの排他的所有権を既に持っていると思っているときに、誤ってリソースの排他的所有権を取得したくはありません。

于 2011-01-02T00:09:18.523 に答える
0

コードの修正バージョン ( return std::auto_ptr<Fred>(new Fred())) は正しく有効な C++ です。ただし、create()関数を作成することはstd::auto_ptr<T>C++ プログラマーのスキル セットの範囲内である必要があるという点で、この関数が何をもたらすかはわかりません。typedef同様に、 が実際に何であるかを調べる必要があることを除けば、 ingが何std::auto_ptr<Fred>FredPtr買うのかはっきりしていませんFredPtr

于 2011-01-02T00:23:27.497 に答える