次のクラスがあると仮定します。
_class MyInteger {
private:
int n_;
public:
MyInteger(int n) : n_(n) {};
// MORE STUFF
};
_
そして、このクラスにデフォルトの単純なコンストラクタMyInteger()
がないと仮定します。何らかの理由でそれを初期化するには、常にint
を提供する必要があります。そして、私のコードのどこかに_vector<MyInteger>
_が必要だとします。この_vector<>
_の各MyInteger
コンポーネントを初期化するにはどうすればよいですか?
私は2つの状況があります(おそらく解決策は同じですが、とにかくそれらを述べます)、関数内の通常の変数:
_int main(){
vector<MyInteger> foo(10); //how do I initialize each
//MyInteger field of this vector?
doStuff(foo);
}
_
クラス内のデータとして:
_class MyFunClass {
private:
vector<MyInteger> myVector;
public:
MyFunClass(int size, int myIntegerValue) : myVector(size) {};
// what do I put here if I need the
// initialization to call MyInteger(myIntegerValue) for all
// components of myVector?
};
_
初期化リストだけでそれを行うことは可能ですか、またはMyFunClass(int、int)コンストラクターで手動で初期化を記述する必要がありますか?
これは非常に基本的なように思えますが、それでも私の本で見逃してしまい、ウェブで見つけることができません。
そこに到達する多くの方法があります。それらのいくつかを以下に示します(特定の順序ではありません)。
vector(size_type n, const T& t)
コンストラクターを使用します。 n
のt
コピーでベクターを初期化します。例えば:
#include <vector>
struct MyInt
{
int value;
MyInt (int value) : value (value) {}
};
struct MyStuff
{
std::vector<MyInt> values;
MyStuff () : values (10, MyInt (20))
{
}
};
要素を1つずつベクトルにプッシュします。これは、値が異なる必要がある場合に役立ちます。例えば:
#include <vector>
struct MyInt
{
int value;
MyInt (int value) : value (value) {}
};
struct MyStuff
{
std::vector<MyInt> values;
MyStuff () : values ()
{
values.reserve (10); // Reserve memory not to allocate it 10 times...
for (int i = 0; i < 10; ++i)
{
values.Push_back (MyInt (i));
}
}
};
C++ 0xがオプションの場合、別のオプションはコンストラクター初期化リストです。
#include <vector>
struct MyInt
{
int value;
MyInt (int value) : value (value) {}
};
struct MyStuff
{
std::vector<MyInt> values;
MyStuff () : values ({ MyInt (1), MyInt (2), MyInt (3) /* ... */})
{
}
};
もちろん、デフォルトのコンストラクタを提供したり、std::vector
以外の何かを使用したりするオプションがあります。
それが役に立てば幸い。
ベクターの要素がデフォルトで構築できない場合、ベクターでできないことがいくつかあります。これを書くことはできません(例1):
vector<MyInteger> foo(10);
ただし、これを書くことができます(例2):
vector<MyInteger> foo(10, MyInteger(37));
(これには、コピーコンストラクタのみが必要です。)2番目の引数は、ベクトルの要素の初期化子です。
あなたの場合、次のように書くこともできます:
vector<MyInteger> foo(10, 37);
... MyIntegerには引数として「int」をとる非明示的なコンストラクターがあるためです。したがって、コンパイラーは37をMyInteger(37)にキャストし、例2と同じ結果を返します。
std :: vectorのドキュメント を調べてください。
質問に非常によく答えたすべての回答に加えて、クラスMyIntegerがコピー構築可能でない場合、このトリックを使用できます。vector< MyInteger>
を作成する代わりに、vector< shared_ptr< MyInteger > >
を作成できます
vector<MyInteger> foo(10, MyInteger(MY_INT_VALUE));
MyFunClass(int size, int myIntegerValue) : myVector(size, MyInteger(myIntegerValue)) {};
初期化リストは、基礎となるオブジェクトを参照せずに使用できます。
#include <string>
#include <vector>
using namespace std;
class Test
{
public:
struct NumStr
{
int num;
string str;
};
Test(vector<int> v1,vector<NumStr> v2) : _v1(v1),_v2(v2) {}
vector<int> _v1;
vector<NumStr> _v2;
};
int main()
{
Test t={ {1,2,3}, {{1,"one"}, {2,"two"}, {3,"three"}} };
cout << t._v1[1] << " " << t._v2[1].num << " " << t._v2[1].str << endl;
return 0;
}
出力:2 2 2