简体   繁体   English

C ++-无法从'char []'转换为'char []'

[英]C++ - Cannot convert from 'char []' to 'char[]'

So I am very new to C++, and having a background in dynamic languages this is probably a newbie question. 因此,我对C ++非常陌生,并且拥有动态语言背景,这可能是一个新手问题。 I was trying to write an age-old exercise, see below: 我正在尝试编写一个古老的练习,请参见下文:

class Person
{
public:
    Person(char n[], int a) {           
        name = n;
        age = a;
    }

    int age;
    char name[];

};

int main(int argc, char const *argv[])
{
    Person p("John", 25);
    return 0;
}

This throws the error: 这引发了错误:

main.cpp(8) : error C2440: '=' : cannot convert from 'char []' to 'char []'
        There are no conversions to array types, although there are conversions
to references or pointers to arrays

Why does it need to convert from the same type? 为什么需要从相同类型转换? This is my full code and full error, by the way. 顺便说一下,这是我的完整代码和完整错误。 Any help is appreciated! 任何帮助表示赞赏!

There is a type called char [] , but it's an incomplete array type which is a somewhat advanced topic. 有一个叫做char []的类型,但是它是一个不完整的数组类型 ,这是一个有点高级的话题。 If it were compiling in strict mode, the compiler would have reported that an incomplete array cannot be a class member, and that should prevent the error you got. 如果以严格模式进行编译,则编译器将报告一个不完整的数组不能为类成员,这应该可以防止出现错误。 But actually you stumbled upon a GCC extension which is seldom compatible with C++ as it requires memory allocation by malloc . 但是实际上您偶然发现了GCC扩展,该扩展很少与C ++兼容,因为它需要通过malloc分配malloc

Anyway, C++ does indeed have variable-length strings in the library, albeit not as a "native" type. 无论如何,C ++确实确实在库中具有可变长度的字符串,尽管不是“本机”类型。 You need to include <string> , and it is called std::string . 您需要包含<string> ,它称为std::string

#include <string>

class Person
{
public:
    Person(std::string n, int a) {           
        name = n;
        age = a;
    }

    int age;
    std::string name;

};

int main(int argc, char const *argv[])
{
    Person p("John", 25);
    return 0;
}

Arrays are not assignable. 数组不可分配。 You have to copy elements on each index to the other iteratively. 您必须将每个索引上的元素迭代地复制到另一个。 For character arrays, you can use strcpy. 对于字符数组,可以使用strcpy。

int a[5], b[5];

a = b; // Error

You should specify the size of the array. 您应该指定数组的大小。 Use std::string instead of working on character arrays. 使用std :: string而不是处理字符数组。

There are multiple errors in your code: 您的代码中存在多个错误:

  1. The type of n is char* : it is not an array but a pointer. n的类型为char* :它不是数组而是指针。 You cannot pass built-in arrays as value parameters. 您不能将内置数组作为值参数传递。 You could pass it as a reference, though, eg using char const (&n)[5] (I'll get to the const below). 不过,您可以将其作为参考传递,例如,使用char const (&n)[5] (我将在下面找到const )。
  2. Even if you pass an array name is an array with no elements and actually illegal! 即使您传递数组name也是没有元素的数组,实际上是非法的! You need to use a positive size for an array. 您需要为数组使用正大小。
  3. Lets assume you declared name as a member of type char name[5]; 假设您将name声明为char name[5];类型的成员char name[5]; and n as a reference to an array, you still wouldn't be able to assign these because arrays cannot be assigned. n作为对数组的引用,由于无法分配数组,您仍然将无法分配它们。 You could, however, copy them using, eg, 但是,您可以使用以下方式复制它们:

     std::copy(std::begin(n), std::end(n), std::begin(name)); 
  4. The type of a string literal is char const[N] with N being the number of characters in the string literal. 字符串文字的类型为char const[N]其中N为字符串文字中的字符数。 You cannot assign that to char* . 您不能将其分配给char* In C++03 the assignment was required to be supported but deprecated and in C++11 the assignment isn't allowed anymore (although it is likely that compiler will allow it unless you enable a strict mode). 在C ++ 03中,必须支持该赋值但不建议使用该赋值;在C ++ 11中,该赋值不再被允许(尽管除非您启用严格模式,否则编译器将允许该赋值)。

  5. Not an error but a note: you should initialize your members, where possible, in the member initializer list, eg (assuming the member name has a suitable type): 不是错误,而是一条注释:您应该尽可能在成员初始值设定项列表中初始化成员,例如(假设成员name具有适当的类型):

     Person(char const* n, int a) : age(a) { strncpy(this->name, n, sizeof(this->name)); } 

I compile the example code in g++ and what's going on becomes a little clearer: 我用g ++编译了示例代码,随后发生的事情变得更加清晰了:

so.cpp:5:16: error: incompatible types in assignment of ‘char*’ to ‘char [0]’

This zero-length array is a "flexible array member". 该零长度数组是“柔性数组成员”。 It must be the last data member of the class, and as with other arrays, you can't assign to it. 它必须是该类的最后一个数据成员,并且与其他数组一样,不能将其分配给它。 If you can't use std::string for some reason, such as if your C++ module needs to present a certain API to C modules, try changing the last line of Person as follows: 如果由于某种原因而无法使用std::string ,例如您的C ++模块需要向C模块提供特定的API,请尝试如下更改Person的最后一行:

    const char *name;

This will result in a working program with a const-correctness warning, which can be fixed by changing the first line of the constructor: 这将导致一个带有const-correctness警告的工作程序,可以通过更改构造函数的第一行来对其进行修复:

    Person(const char n[], int a) {

The final program, which compiles without warnings in g++: 最终程序,在g ++中编译时不会发出警告:

#include <cstdio>
class Person
{
public:
    Person(const char n[], int a) {           
        name = n;
        age = a;
    }

    int age;
    const char *name;

};

int main(int argc, char const *argv[])
{
    Person p("Jack", 14);
    std::puts(p.name);
    return 0;
}

Here is the error I get from g++ 这是我从g ++得到的错误

$ g++ -Wall example.cc -o example
example.cc: In constructor ‘Person::Person(char*, int)’:
example.cc:5:16: error: incompatible types in assignment of ‘char*’ to ‘char [0]’
example.cc: In function ‘int main(int, const char**)’:
example.cc:16:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

If I substitute char n[] and char name[] with char *n and char *name , you get 如果我用char *nchar *name替换char n[]char name[] ,则得到

$ g++ -Wall example.cc -o example
example.cc: In function ‘int main(int, const char**)’:
example.cc:16:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

I'm not sure why the compiler likes char* 's better in this case, but it does make more sense to use char* 's when representing strings in general. 我不确定为什么在这种情况下编译器更喜欢char* ,但是在一般表示字符串时使用char*确实更有意义。

Since you are writing in C++, the type std::string is generally preferred since it is more type-safe than char* . 由于您使用C ++编写代码,因此通常首选std::string类型,因为它比char*类型安全。 This will make code that compiles more robust. 这将使编译的代码更健壮。

Will all of that in mind, I would write the following code 请记住所有这些,我将编写以下代码

#include <string>

class Person
{
public:
    Person(std::string n, int a) {           
        name = n;
        age = a;
    }

    int age;
    std::string name;

};

int main(int argc, char const *argv[])
{
    Person p("Jack", 14);
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM