C++ Error: Incompatible types in assignment of ‘char*’ to ‘char [2]

匿名 (未验证) 提交于 2019-12-03 02:20:02

问题:

I have a bit of a problem with my constructor. In my header file I declare:

char short_name_[2];  
  • and other variables

In my constructor:

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_; } 

In my cpp file:

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

My error:

Territory.cpp: In constructor ‘Territory::Territory(std::string, char*, Player*, char)’: Territory.cpp:15:33: error: incompatible types in assignment of ‘char*’ to ‘char [2]’

I already figured out that char[2] <=> char* but I'm not sure how to handle this about my constructor and get/setters.

回答1:

Raw arrays in C++ are kind of annoying and fraught with peril. This is why unless you have a very good reason to you should use std::vector or std::array.

First off, as others have said, char[2] is not the same as char*, or at least not usually. char[2] is a size 2 array of char and char* is a pointer to a char. They often get confused because arrays will decay to a pointer to the first element whenever they need to. So this works:

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

But the reverse does not:

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

Adding to the confusion, when declaring function parameters, char[] is equivalent to char*. So in your constructor the parameter char short_name[2] is really char* short_name.

Another quirk of arrays is that they cannot be copied like other types (this is one explanation for why arrays in function parameters are treated as pointers). So for example I can not do something like this:

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

Instead I have to iterate over the elements of foo and copy them into bar, or use some function which does that for me such as 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)); 

So in your constructor you have to manually copy the elements of short_name into short_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)); } 

As you can see this is all very annoying, so unless you have a very good reason you just should use std::vector instead of raw arrays (or in this case probably std::string).



回答2:

When a function wants an array as argument, it gets a pointer to the first element of an array instead. This pointer cannot be used to initialize an array, because it's a pointer, not an array.

You can write functions that accept references to arrays as arguments:

void i_dont_accept_pointers(const char (array&)[2]) {} 

The problem here is, that this array reference cannot be used to initialize another array.

class Foo {   char vars[2];   Foo(const char (args&)[2])     : vars(args)  // This will not work   {} }; 

C++ 11 introduced std::array to eliminiate this and other problems of arrays. In older versions, you will have to iterate through the array elements and copy them individually or use std::copy.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!