4

2つMyVec作成されていますか?MyVecコンストラクターのassinmentの前に、デフォルトで構築された一時的なものが存在しFooますか?

struct Foo {

  typedef std::vector<int> MyVec;

  Foo () {

    // determine how big the vector needs to be.
    // .....

    m_vec = MyVec(12);
  }

  MyVec m_vec; 
};

私はポインターを使ってそれができることを知っています。

struct Foo {

  typedef std::vector<int> MyVec;

  Foo () {
    m_vec = new MyVec();
  }

  ~Foo () {
    delete m_vec;
  }

  MyVec * m_vec;
};

しかし、可能であればそれを避けたいと思います。

編集:

言及するのを忘れました。代入の前にコンストラクターで何かをする必要があるため、初期化子リストを使用できません。

4

3 に答える 3

6

代わりに次の構文を試してください。

struct Foo {

  typedef std::vector<int> MyVec;

  Foo ()
  : m_vec(12)
  {
  }

  MyVec m_vec; 
};

これは、c++メンバー初期化リストと呼ばれます。


代入の前にコンストラクターで何かをする必要があるため、初期化子リストを使用できません。

ベクトルの大きさを計算する必要がある場合は、コンストラクターを呼び出す前に、またはコンストラクターから呼び出す静的メソッドで計算できます。

struct Foo {

  typedef std::vector<int> MyVec;

  Foo ()
  : m_vec(calculateVectorSize())
  {
  }

  static int calculateVectorSize()
  {
      // determine how big the vector needs to be.
      // .....
  }

  MyVec m_vec; 
};

それらも不可能な場合は、元の投稿よりも安価な解決策は次のとおりです。

struct Foo {

  typedef std::vector<int> MyVec;

  Foo () {

    // determine how big the vector needs to be.
    // .....

    m_vec.resize(12);
  }

  MyVec m_vec; 
};
于 2012-12-05T17:23:45.183 に答える
1

はい。

そして、はい、あなたはそれを避けることができます:

Foo():
  m_vec(/*args_to_construct_m_vec*/)
{
  // body goes here
}

上記の構文を介して。

何を入れるかを作業したいために初期化子リストを使用できない場合m_vec、別のアプローチはクラスを分割することです。

のサイズを計算する前に初期化する必要があるクラスの部分はm_vec、親クラスにスタックします。それを作成m_vecしてから、初期化子リストで作成します。

std::vectorデフォルトの初期化はかなり安価であることに注意してください(通常は " memset" sizeof(3ポインター)から0)。そのため、懸念はほぼ間違いなく見当違いです。

于 2012-12-05T17:24:17.750 に答える
1

typedefは、ベクトルライブラリが含まれていることをgvienと見なすMyVecことができるコンパイラに通知しているだけだと思います。vector<int>

ただし、実際MyVecにはまだ作成されていません。

また、メンバーフィールドを初期化するための代替のより好ましい構文を試す必要があります。

于 2012-12-05T17:27:45.020 に答える