将静态数组定义到C或C ++源文件中

时间:2011-01-10 09:51:11

标签: c++ c arrays static

我知道这是每个程序员都应该知道的问题,但我不知道。很久没有C编程了,我忘了很多东西。

我的问题是:

我在头文件中定义了三个巨大的静态数组。有人告诉我,最好在头文件中将它们声明为extern,并在单个C或C ++源文件中定义它们。

我该怎么做?

这是我的头文件:

#ifndef _TEMPLE_OBJECT_H_
#define _TEMPLE_OBJECT_H_


#define NUM_TEMPLE_OBJECT_VERTEX 10818

static const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
static const float TEMPLENormals[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
static const float TEMPLETexCoords[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};

#endif

如果使用C ++源文件,我可能需要定义一个类吗?

更新:
我认为问题是:
包含这些头的每个源文件(甚至是间接的)将为这些静态数组生成自己的定义。无法保证编译器/链接器会将它们优化为单个定义,即使在未使用它们的源文件中也是如此。事实上,在许多情况下,编译器无法优化它们。这可能会导致静态数据消耗大量磁盘空间,并可能导致运行时内存。

谢谢。

5 个答案:

答案 0 :(得分:18)

staticextern同时毫无意义。文件范围内的static使得其他文件无法访问该数组,而extern告诉编译器您的数组已在其他位置定义。

您可以执行321008建议的操作,除了您没有声明您的数组静态这是非法的C和C ++。这为您提供了三个全局变量,您可以在包含头文件的任何位置使用它们。

例如:

// .h file:

extern const float TEMPLEVertices[];

// .cpp (or .c) file:

const float TEMPLEVertices[] = { 1.0, 2.0, 5.6 /* or whatever*/ };

或者你可以做fortran所建议的,但这只会给你文件范围访问权限,而不是全局变量。

如果您使用C ++源文件,则必须以任何方式定义类。与Java不同,C ++不会强迫您进入面向对象的设计(无论是否可以讨论,但无论如何都可以讨论它。)

编辑:至于您的问题更新,那是因为您将其定义为static。如果您只想要全局变量,则不应该这样做,而是保留一个单一定义(const float)并使用extern引用它,如上面的示例所示。

答案 1 :(得分:7)

我曾经在Quake2源代码中看到一个有趣的“技巧”,实际上这只是一种使用包含的不寻常方式:

只是这样做:

static const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {
#include "TEMPLEVertices.txt"
};

并保留所包含文件中的数据。

你仍然可以在编译单元中将它们声明为extern,但这会使事情变得更加整洁。

答案 2 :(得分:5)

您的标头文件变为:

#ifndef _TEMPLE_OBJECT_H_
#define _TEMPLE_OBJECT_H_


#define NUM_TEMPLE_OBJECT_VERTEX 10818

extern const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3];
extern const float TEMPLENormals[NUM_TEMPLE_OBJECT_VERTEX * 3];
extern const float TEMPLETexCoords[NUM_TEMPLE_OBJECT_VERTEX * 3];

#endif

您的源文件变为:

// include header
const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
const float TEMPLENormals[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
const float TEMPLETexCoords[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};

// rest of the source

更新:如果您明确指定数组,则不必提及大小。那就是你可以做到的:

const float TEMPLEVertices[] = {...};

const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3];

答案 3 :(得分:5)

实际上,它非常简单;我将用一个更简单的例子来演示一个简单的原始常量。

在您的项目中,您有两个文件pi.hpi.cpp

pi.h的内容如下所示:

#ifndef _PI_H
#define _PI_H

extern const double PI;

#endif

pi.cpp的含义如下:

#include "pi.h"

const double PI = 3.1415926535;

如果您想使用此常量,只需在必要时包含pi.h即可。该值将始终从同一位置读取。

几乎可以做任何事情 - 数组,对象,对象数组,STL容器等。请确保不要过度使用此技术 - 尤其是当声明extern的对象不是{{1}时,你可能会创建一些非常难以跟踪的副作用。但是对于不断的数据,你就是这样做的。

答案 4 :(得分:0)


我通常使用一个简单的技巧。

a)在每个C / CPP文件中,我定义 filename _C
b)在每个H / HPP文件中,我定义 filename _H

...比

这将是您的包含文件

#ifndef _TEMPLE_OBJECT_H_
#define _TEMPLE_OBJECT_H_

#define NUM_TEMPLE_OBJECT_VERTEX 10818

#ifdef _TEMPLE_OBJECT_C
const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...} ; /* Put here your const values */
#else
extern const float TEMPLEVerticies[] ;
#endif

#endif

如果我没错,这应该是(或与此类似的东西)......:o)