嘿家伙!当我尝试在头文件中执行以下操作时将静态const char []设置为预定义的静态const char []失败
static const char FOOT[] = "Foot";
static const char FEET[] = FOOT;
我收到编译器错误error: initializer fails to determine size of FEET
。我想知道这是什么原因,以及是否有办法纠正它。谢谢!
嘿家伙!当我尝试在头文件中执行以下操作时将静态const char []设置为预定义的静态const char []失败
static const char FOOT[] = "Foot";
static const char FEET[] = FOOT;
我收到编译器错误error: initializer fails to determine size of FEET
。我想知道这是什么原因,以及是否有办法纠正它。谢谢!
即使你为什么得到这个错误已经回答了,还有更多的故事。如果你真的需要换脚是一个数组,那么你可以把它的引用,而不是指针:(该inside-out rule的更多示例)
char const foot[] = "foot";
char const (&feet)[sizeof foot] = foot;
// reference to array (length 5) of constant char
// (read the declarations "from the inside-out")
char const* const smelly_feet = foot;
// constant pointer to const char
int main() {
cout << sizeof feet << ' ' << feet << '\n';
cout << sizeof smelly_feet << ' ' << smelly_feet << '\n';
cout << sizeof(void*) << " - compare to the above size\n";
return 0;
}
其次,static
在文件和命名空间范围意味着内部联系;所以当你在标题中使用它时,你会在每个使用该标题的TU中获得重复的对象。有些时候你想要这样做,但是在你的代码中没有看到它的原因,这是一个常见的错误。
关于阵列尺寸:的sizeof
操作者返回一个类型的对象或实例的内存大小。对于数组来说,这意味着所有项目的总内存大小。由于C++保证sizeof(char)
为1,因此char数组的内存大小与其长度相同。对于其他数组类型,你可以通过一个项目的内存大小划分得到一个数组的长度:
void f() {
int array[5];
assert((sizeof array/sizeof *array) == 5);
}
而且你可以把它推广到函数模板:
template<class T, int N>
int len(T (&)[N]) {
return N;
}
// use std::size_t instead of int if you prefer
这存在提升为boost::size。
您可能会看到使用sizeof array/sizeof *array
的代码,无论是通过宏还是直接使用,或者是因为它过时或不想使事情复杂化。
原因是你说FEET []是一个字符数组,但是你将它初始化为一个ptr; 要纠正,你可以改变从脚脚[]为* FEET 也可以做同样的FOOT
感谢您的解释 – spbots 2009-11-18 20:52:18
一种方式是这个
static const char FOOT[] = "Foot";
static const char *FEET = FOOT;
有在C数组没有“=”操作符++ ,你需要使用strcpy或类似的东西(你不能用静态常量来做)。根据您的要求下面可能是有用的:
#define contentsOfFoot "FOOT"
static const char FOOT[5] = contentsOfFoot;
static const char FEET[5] = contentsOfFoot;
static const char *feeet = FOOT;
原代码不使用'='运算符。原始代码执行初始化。 '='在初始化时不是'='运算符。 – AnT 2009-11-18 21:42:41
不推荐使用static,而且命名空间范围内的const变量实际上是静态的。另外,请为预处理器标识符保留ALL_CAPS。
更大的问题是你为什么要使用原始数组。你很可能需要更多的东西是这样的:
std::string const foot = "foot";
std::string const feet = foot;
或者,更有可能:
#include <string>
namespace spbots {
typedef std::string string_t;
string_t const foot = "foot";
string_t const feet = foot;
}
我想强调的是,你不应该把这些东西在头文件。变量只能放在头文件中,如果你想使它们全局可见(通常不是一个好主意,但它是一种合法的技术)。
feet.h
extern char feet[];
feet.cpp
char feet[] = "FEET";
现在,当您在一个不同 .cpp文件feet.h,说leg.cpp,在feet.h的声明意味着leg.cpp可以看到和使用feet.cpp
定义的阵列extern关键字与您使用的static关键字具有相反的含义。静态的典型用法如下;
feet.cpp
static char feet[] = "FEET";
现在脚[]在feet.cpp之外明显不可见。 static关键字负责这种缺乏可见性。所以静态=本地,外部=全球和(可能不幸?)外部是默认的,所以如果你不使用任何关键字,你会得到外部不管你喜欢还是不喜欢。
因为static = local,所以没有什么可以与其他模块通信,所以不需要在头文件中声明其他模块的声明。一切都保存在feet.cpp中,可能比全局变量更好。
另一点我隐含地试图解决这个问题,就是声明进入头文件,定义进入.cpp文件。在你的问题中你有一个头文件的定义。不是非法的,但是如果你将它包含在多个文件中(如果你不这样做,为什么要把它放在一个头文件中?),你会得到多次定义的单个变量,这会给你一个链接错误。
所有这些实际上都是古老的C而不是现代意义上的C++。换句话说,你真的在写C,但由于C(几乎)是C++的一个子集,你仍然可以使用C++来完成这些工作。
+1,因为它最接近声明的要求,并且因为引用/数组指针是鲜为人知和理解的,它需要修复:)但是,我还使用'sizeof'而不是使用硬编码大小来声明'脚'。 – 2009-11-18 22:14:33
好的建议,修正。 – 2009-11-18 22:21:58
这是一个很好的答案,感谢所有的信息;每天都必须学习新的东西! – spbots 2009-11-19 15:51:15