11

我的构造函数有点问题。在我的头文件中,我声明:

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, char*, Player*, char)”中:Territory.cpp:15:33:错误:将“char*”分配给“char [ 2]'</p>

我已经想通了,char[2] <=> char*但我不确定如何处理我的构造函数和 get/setter。

4

3 回答 3

18

C++ 中的原始数组有点烦人且充满危险。这就是为什么除非你有很好的理由你应该使用std::vectoror std::array

首先,正如其他人所说,char[2]与 不一样char*,或者至少通常不一样。char[2]是一个大小为 2 的数组,char并且char*是指向 a 的指针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)。

于 2013-04-10T00:15:08.430 回答
2

当一个函数想要一个数组作为参数时,它会得到一个指向数组第一个元素的指针。该指针不能用于初始化数组,因为它是指针,而不是数组。

您可以编写接受对数组的引用作为参数的函数:

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

这里的问题是,这个数组引用不能用于初始化另一个数组。

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

引入 C++ 11std::array以消除数组的这个问题和其他问题。在旧版本中,您必须遍历数组元素并单独复制它们或使用std::copy.

于 2013-04-09T23:45:41.713 回答
0

C++ 作为 C 持有 C 的大部分规则。

在 C 的情况下,总是使用 char* 来传递数组,因为 C 是这样看待它的。sizeof (short_name_)传递给函数时,偶数将为 8 或 4。现在,变量中有 2 个字节的空间short_name_

构造函数为两个字节分配了内存,short_name_您需要将字节复制到其中或使用 char * 指针并假设它的大小为 2。

Expert C Programming: Deep C Secrets的第 9 章很适合阅读以理解它。

为简单起见,这可能是 C 风格的代码。

#include <stdio.h>
#include <iostream>
using namespace std;
class Territory {
    private:
        string s;
        char c[2];
    public:
    Territory(std::string a, char b[2] /*visualize as char *b*/) {
        s  = a;
        c[0] = b[0]; //or use strcpy
        c[1] = b[1];
    }
    void PrintMe() {
        printf ("As string %s as char %c or %s\n",this->s.c_str(), c[0],c);
    }
};


main () {
    Territory a("hello", "h");
    a.PrintMe();
}
于 2019-10-19T10:18:08.793 回答