0

所以我对 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

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

4

5 回答 5

3

有一种类型叫做char [],但它是一个不完整的数组类型,这是一个有点高级的话题。如果它在严格模式下编译,编译器会报告一个不完整的数组不能是类成员,这应该可以防止你得到的错误。但实际上你偶然发现了一个很少与 C++ 兼容的 GCC 扩展,因为它需要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;
}
于 2013-09-05T00:51:46.420 回答
1

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

int a[5], b[5];

a = b; // Error

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

于 2013-09-05T00:39:54.770 回答
1

您的代码中有多个错误:

  1. 的类型nchar*:它不是数组而是指针。您不能将内置数组作为值参数传递。不过,您可以将它作为参考传递,例如使用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 中不再允许分配(尽管编译器可能会允许它,除非您启用严格模式)。

  5. 不是错误,而是注意事项:您应该在可能的情况下在成员初始化器列表中初始化您的成员,例如(假设成员name具有合适的类型):

    Person(char const* n, int a)
        : age(a)
    {
        strncpy(this->name, n, sizeof(this->name));
    }
    
于 2013-09-05T00:49:55.833 回答
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;
}
于 2013-09-05T00:46:03.147 回答
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]

如果我用andchar n[]代替 and ,你会得到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]

我不确定为什么编译器在这种情况下更喜欢's,但通常在表示字符串时char*使用 's 确实更有意义。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;
}
于 2013-09-05T01:00:41.140 回答