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

时间:2013-09-05 00:35:25

标签: c++ types char

所以我对C ++很陌生,并且拥有动态语言的背景,这可能是一个新手问题。我试图写一个古老的练习,见下文:

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

这会引发错误:

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

为什么需要从同一类型转换?顺便说一句,这是我的完整代码和完整错误。任何帮助表示赞赏!

5 个答案:

答案 0 :(得分:3)

有一种名为char []的类型,但它是不完整的数组类型,这是一个有点高级的主题。如果它是在严格模式下编译,编译器会报告一个不完整的数组不能是类成员,这应该可以防止你得到的错误。但实际上你偶然发现了一个GCC扩展,它很少与C ++兼容,因为它需要malloc的内存分配。

无论如何,C ++确实在库中有可变长度的字符串,尽管不是“本机”类型。您需要添加<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;
}

答案 1 :(得分:1)

数组不可分配。您必须迭代地将每个索引上的元素复制到另一个索引。对于字符数组,您可以使用strcpy。

int a[5], b[5];

a = b; // Error

您应该指定数组的大小。使用std::string而不是处理字符数组。

答案 2 :(得分:1)

您的代码中存在多个错误:

  1. n的类型为char*数组而是指针。您不能将内置数组作为值参数传递。您可以将其作为参考传递,例如,使用char const (&n)[5](我将转到下面的const)。
  2. 即使您传递数组name也是一个没有元素的数组,实际上是非法的!您需要为数组使用正大小。
  3. 让我们假设您将name声明为类型char name[5];n的成员作为对数组的引用,您仍然无法分配这些因为数组无法分配。但是,您可以使用例如

    复制它们
    std::copy(std::begin(n), std::end(n), std::begin(name));
    
  4. 字符串文字的类型为char const[N]N是字符串文字中的字符数。您无法将其分配给char*。在C ++ 03中,需要支持赋值但不推荐使用,并且在C ++ 11中不再允许赋值(尽管除非启用严格模式,否则编译器可能会允许它)。

    < / LI>
  5. 不是错误而是注释:您应该尽可能在成员初始化列表中初始化您的成员,例如: (假设成员name具有合适的类型):

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

答案 3 :(得分:0)

我用g ++编译示例代码,然后发生的事情变得更加清晰:

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

这个零长度数组是一个“灵活的数组成员”。它必须是类的最后一个数据成员,并且与其他数组一样,您无法分配它。如果由于某种原因无法使用std::string,例如,如果您的C ++模块需要向C模块提供某个API,请尝试更改Person的最后一行,如下所示:

    const char *name;

这将导致一个带有const-correctness警告的工作程序,可以通过更改构造函数的第一行来修复:

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

最终的程序,在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;
}

答案 4 :(得分:0)

这是我从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]

如果我将char n[]char name[]替换为char *nchar *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]

我不确定为什么编译器在这种情况下更喜欢char*,但在表示字符串时使用char*更有意义。

由于您使用C ++编写,因此类型std::string通常是首选,因为它比char*更安全。这将使编译更健壮的代码。

考虑到所有这些,我会写下面的代码

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