カスタムクラスで配列を宣言しようとしています。クラスにコンストラクターを追加すると、コンパイラーは「name [3]の初期化に一致するコンストラクターがない」と文句を言います。
私のプログラムは次のとおりです。
#include <iostream>
using namespace std;
class name {
public:
string first;
string last;
name(string a, string b){
first = a;
last = b;
}
};
int main (int argc, const char * argv[])
{
const int howManyNames = 3;
name someName[howManyNames];
return 0;
}
この実行を行うために私は何ができますか、そして私は何を間違っていますか?
デフォルトのコンストラクタを提供する必要があります。その間、他のコンストラクタも修正します。
class Name
{
public:
Name() { }
Name(string const & f, string const & l) : first(f), last(l) { }
//...
};
または、初期化子を提供する必要があります。
Name arr[3] { { "John", "Doe" }, { "Jane", "Smith" }, { "", "" } };
あなたのクラスshouldが「デフォルト」状態の概念を持つ理由はないので、後者は概念的に望ましいです。その場合、単にhaveを使用して、配列のすべての要素に適切な初期化子を提供します。
C++のオブジェクトが不明確な状態になることはありません。これについて考えると、すべてが非常に明確になるはずです。
代替手段はdynamicコンテナを使用することですが、これはあなたが要求したものとは異なります:
std::vector<Name> arr;
arr.reserve(3); // morally "an uninitialized array", though it really isn't
arr.emplace_back("John", "Doe");
arr.emplace_back("Jane", "Smith");
arr.emplace_back("", "");
std::vector<Name> brr { { "ab", "cd" }, { "de", "fg" } }; // yet another way
T
sの配列をデフォルトで初期化するには、T
がデフォルトで構築可能でなければなりません。通常、コンパイラはデフォルトのコンストラクタを無料で提供します。ただし、コンストラクタを自分で宣言したため、コンパイラはデフォルトのコンストラクタを生成しません。
あなたのオプション:
宣言時に配列のすべての要素を初期化します(name
は集約であるため、これを行うことができます);
name someName[4] = { { "Arthur", "Dent" },
{ "Ford", "Prefect" },
{ "Tricia", "McMillan" },
{ "Zaphod", "Beeblebrox" }
};
使う std::vector
代わりに、構築した要素のみを追加します。
オブジェクトの配列を作成するために、オブジェクトにはパラメーターを使用しないコンストラクターが必要です(たとえば、両方の文字列が空のオブジェクトのデフォルトのフォームを作成します)。これがエラーメッセージの意味です。コンパイラーは、空のオブジェクトを作成するコンストラクターを自動的に生成しますnless他のコンストラクターがあります。
空の配列要素を作成するのが理にかなっている場合(この場合、メンバーはデフォルト値、この場合は空の文字列を取得します):
-空のコンストラクターを作成します。
_class name {
public:
string first;
string last;
name() { }
name(string a, string b){
first = a;
last = b;
}
};
_
-または、必要ない場合は、既存のコンストラクタを削除します。
クラスの「空の」バージョンが意味をなさない場合、コンパイル時に配列のすべての要素に初期化パラメーターを提供する良い解決策はありません。あなたはできる:
init()
関数を作成させますvector
を使用し、初期化時に_vector::insert
_またはループを使用してオブジェクトを作成し、vector
に挿入し、コンパイル時に実行しないことを信頼します。案件。_std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" };
_
`
クラスのインスタンスを作成するには、 パラメーターなしのコンストラクター が必要です。現在のコンストラクタには、2つの入力文字列パラメーターが必要です。
通常、C++は、他のコンストラクターが宣言されていない場合、そのようなコンストラクター(= defaultパラメーターレスコンストラクター)を持つことを意味します。 2つのパラメーターを使用して最初のコンストラクターを宣言すると、このデフォルトの動作が上書きされ、このコンストラクターを明示的に宣言する必要があります。
作業コードは次のとおりです。
#include <iostream>
#include <string> // <-- you need this if you want to use string type
using namespace std;
class name {
public:
string first;
string last;
name(string a, string b){
first = a;
last = b;
}
name () // <-- this is your explicit parameterless constructor
{}
};
int main (int argc, const char * argv[])
{
const int howManyNames = 3;
name someName[howManyNames];
return 0;
}
(ところで、コードをコンパイル可能にするために含める必要があります。)
別の方法は、宣言時にインスタンスを明示的に初期化することです
name someName[howManyNames] = { {"Ivan", "The Terrible"}, {"Catherine", "The Great"} };
クラスにデフォルトのコンストラクタを追加するだけで、次のようになります。
class name {
public:
string first;
string last;
name() {
}
name(string a, string b){
first = a;
last = b;
}
};
あなたのクラス:
class name {
public:
string first;
string last;
name() { } //Default constructor.
name(string a, string b){
first = a;
last = b;
}
};
2つの文字列パラメーターを必要とするexplicitコンストラクターがあります。コンストラクタが明示的に記述されていないクラスは、パラメータを取らないデフォルトのコンストラクタを取得します。明示的なものを追加すると、コンパイラはデフォルトのコンストラクタを生成しなくなりました。
したがって、初期化されていないオブジェクトの配列を作成する場合は、クラスにデフォルトコンストラクターを追加して、これらの2つの文字列パラメーターを指定せずにコンパイラーがそれらを作成する方法を認識できるようにします(上記のコメント行を参照)。