1. ホーム
  2. c++

[解決済み] C++エラー。char*' から 'char [2] への代入で互換性のない型がある。

2022-02-28 02:14:22

質問

コンストラクタに少し問題があります。 ヘッダーファイルで次のように宣言しています。

char short_name_[2]; 

  • およびその他の変数

私のコンストラクタでは

Territory(std::string name, char short_name[2], Player* owner, char units);
void setShortName(char* short_name);
inline const char (&getShortName() const)[2] { return short_name_; }

私のcppファイルでは

Territory::Territory(std::string name, char short_name[2], Player* owner, 
                     char units) : name_(name), short_name_(short_name), 
                    owner_(owner), units_(units)
{ }

私のミスです。

Territory.cpp: コンストラクタ「Territory::Territory(std::string.Territory)」にて。 char*, Player*, char)': Territory.cpp:15:33: error: 非互換の型 char*' の 'char [2]' への代入で

もうわかったんですが char[2] <=> char* しかし、コンストラクタやget/setterについて、どのように処理したらよいのかわかりません。

どのように解決するのですか?

C++の生配列は、ある意味厄介で、危険と隣り合わせです。このため、よほどのことがない限りは std::vector または std::array .

まず、他の方もおっしゃっているように char[2] とは異なります。 char* 少なくとも通常ではありません。 char[2] はサイズ2の配列で charchar* へのポインタです。 char . 配列は必要なときにいつでも最初の要素へのポインタに減衰するので、彼らはしばしば混乱します。だから、これはうまくいくのです。

char foo[2];
char* bar = foo;

しかし、逆はそうはいかない。

const char* bar = "hello";
const char foo[6] = bar; // ERROR

さらに混乱を招いたのが、関数のパラメータを宣言するときです。 char[] と同じです。 char* . したがって、コンストラクタのパラメータ char short_name[2] は本当に char* short_name .

配列のもうひとつの特徴は、他の型のようにコピーすることができないことです(関数のパラメータに含まれる配列がポインタとして扱われる理由のひとつはこれです)。したがって、たとえば次のようなことができます。 ない というようなことをします。

char foo[2] = {'a', 'b'};
char bar[2] = foo;

の要素に対して反復処理を行う必要があります。 foo にコピーし bar または、次のような関数を使用してください。 std::copy :

char foo[2] = {'a', 'b'};
char bar[2];
// std::begin and std::end are only available in C++11
std::copy(std::begin(foo), std::end(foo), std::begin(bar));

そのため、コンストラクタの中で、手動で short_nameshort_name_ :

Territory::Territory(std::string name, char* short_name, Player* owner, 
                     char units) : name_(name), owner_(owner), units_(units)
{ 
    // Note that std::begin and std::end can *not* be used on pointers.
    std::copy(short_name, short_name + 2, std::begin(short_name));
}

見ての通り、これは非常に面倒なので、よっぽどの理由がない限りは std::vector の代わりに、生の配列(この場合はおそらく std::string ).