0

私は 2 つのクラスを持っており、一方は他方の中にあり、外側のクラス コンストラクターの本体に内側のクラスを構築したいと考えています。私は正しいコードであるべきだと思うものを持っていますが、それは機能していません。エラー メッセージは、呼び出しに一致する VSL::VSL() がないことを示しているようですが、正しいプロトタイプのようです。

コードは次のようになります。

ヘッダー内:

class VSL
{
    VSL(vector<string> &v, string &s);
};
class KVTest
{
    VSL vsl;
    KVTest(int argc, char *argv[]);
};

体内:

KVTest::KVTest(int argc, char *argv[]) {
    vector<string> v;
    string s;

    vsl(v, s);
}

これは、次のエラー メッセージで失敗します。

src/util/kv-test/kv-test.cpp: In constructor 'KVTest::KVTest(int, char**)':
src/util/kv-test/kv-test.cpp:237: error: no matching function for call to 'VSL::VSL()'
src/util/kv-test/kv-test.cpp:112: note: candidates are: VSL::VSL(std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::string&)
src/util/kv-test/kv-test.h:45: note:                 VSL::VSL(const VSL&)
src/util/kv-test/kv-test.cpp:347: error: no match for call to '(VSL) (std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::string&)'

237 行目は KVTest コンストラクター宣言です 347 行目はそのコンストラクター内で vsl コンストラクターが呼び出される行です 112 行目は VSL コンストラクター宣言です ヘッダーの 45 行目は { VSL クラスの開始です VSL の明示的なコピー コンストラクターはありません

4

2 に答える 2

3

の本体に入るまでにKVTest::KVTestvslはすでに初期化されています。コンストラクターを再度呼び出すことはできません。しかし、デフォルト (引数なし) のコンストラクターがないため、コンパイラ エラー メッセージが表示されます。

次の 2 つのオプションがあります。

  1. のデフォルト コンストラクタを宣言しますVSL
  2. コンストラクタ初期化リストvslを使用して明示的に初期化します。これは通常、次のようになります。

    KVTest::KVTest(int argc, char *argv[])
    : vsl(foo, bar)
    {}
    

    一時変数などを含む複雑な初期化を実行する必要がある場合は、VSL.

于 2012-06-15T22:57:54.317 に答える
1

まず、これは「内部クラス」ではなく、データ メンバーです。

コードを次の宣言と初期化と比較してくださいint

int i = 0;

int次のように記述して を作成することはできません。

i(0);

同様に、これは を構築しませんvsl:

vsl(v, s);

その時点ですでに構築されています。コンストラクターの本体が開始する前に構築されます。または、引数なしで構築できるデフォルトのコンストラクターがある場合は、構築されます。

オブジェクトを構築するには、それを宣言する必要があります:

VSL vsl(v, s);

ただし、メンバー変数の場合は既に宣言されているため、コンストラクター本体でそれを行うことはできません。

デフォルトのコンストラクターがある場合、新しい値を代入することで、コンストラクター本体の変数を更新できます。

vsl = VSL(v, s);

型に正しく記述された代入演算子がある限り。

または、コンストラクター初期化子リストで、適切なタイミングで初期化することもできます。

KVTest::KVTest(int argc, char *argv[])
:vsl( createVSL() )
{
}

これにより、返されたオブジェクトのコピーとして作成されますcreateVSL()

VSL createVSL()
{
  vector<string> v;
  string s;
  VSL vsl(v, s);
  return vsl;
}
于 2012-06-15T23:01:43.520 に答える