在C中,结构声明永远不会生成存储,因此C不会 将结构定义与其他结构声明区分开来。 C ++ 确实。在C ++中,结构声明也是一个定义,如果它有一个 身体,如:
private void MyWnd::onTextChanged() { QStringList wordList = textEdit->toPlainText().split(); foreach (QString word, wordList ) { qDebug() << word; } }
如果它缺少一个正文,它只是一个声明,如:
struct widget // a definition { ... };
那么struct widget; // just a declaration
声明在哪些情况下会在c ++中生成存储?
答案 0 :(得分:3)
以下是我对上述内容的解释,希望更清楚。
struct声明永远不会在C或C ++中生成存储。
由于C不区分结构定义和其他结构声明,因此结构定义也不会在C中生成存储。
在C ++中,带有静态数据成员的结构的定义( nb在C 中没有静态数据成员这样的东西)不能自己生成存储,而是正式声明它静态数据成员,然后需要在封闭范围内定义 - 此时它实际上会生成存储。
换句话说,结构的C ++定义在技术上并不能生成存储,但实际上不能使用,除非其静态数据成员在其他地方定义(使用隐含存储 - 即使没有任何对象该类型是实例化的。)
下面的相关C ++参考资料。
- 3.1.2声明和定义
struct X { // defines X
static int y; // declares static data member y
};
int X::y = 1; // defines X::y
- 9.4.2静态数据成员
9.4.2.1 [...]静态数据成员不是类的子对象的一部分。该类的所有对象只共享一个静态数据成员的副本。
[...]在类定义中声明静态数据成员不是一个定义,除了cv-quali fi ed void之外,它可能是一个不完整的类型。
[...]静态数据成员的定义应出现在包含成员类定义的命名空间范围内。
[...]注意:一旦定义了静态数据成员,即使没有创建其类的对象,它也存在。
答案 1 :(得分:3)
两种情况都没有。问题归结为你链接的文章最好是误导,如果不是错误的话。文章实际上并没有说&#34;生成存储&#34;是两者的必然结果,但它误导了它。我认为,这个措辞很差,而且非常不精确。
不幸的是,标准也不容易阅读,请参阅第3.1节:{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf][1]
简而言之,对于结构定义,声明只引入了类型名称或结构标记&#34; widget&#34;。该定义是一个声明,也提供了定义&#34;定义的主体。类型,就像第一个例子一样。
C ++标准中的示例更容易理解:
示例:以下所有内容均为定义:
int a; // defines a extern const int c = 1; // defines c int f(int x) { return x+a; } // defines f and defines x struct S { int a; int b; }; // defines S, S::a, and S::b struct X { // defines X int x; // defines non-static data member x static int y; // declares static data member y X(): x(0) { } // defines a constructor of X }; int X::y = 1; // defines X::y enum { up, down }; // defines up and down namespace N { int d; } // defines N and N::d namespace N1 = N; // defines N1 X anX; // defines anX
而这些只是声明:
extern int a; // declares a extern const int c; // declares c int f(int); // declares f struct S; // declares S typedef int Int; // declares Int extern X anotherX; // declares anotherX using N::d; // declares d
你可以定义&#34;一种除了定义它的布局之外什么都不做的结构。但你也可以定义&#34;该结构类型的变量。那就是存储可能会被生成&#34; (我可能会说分配或保留)。当定义结构类型的全局变量时,它将导致二进制可执行文件包含结构大小的数据块。如果定义了本地(自动或堆栈)变量,则会在运行时占用执行堆栈上的空间。
例如,如果是全局的(即不在函数中):
struct widget x; // defines variable x of type struct widget
// which must be defined somewhere prior
struct widget2; // declares structure widget2
// does nothing except tells the compiler there will be some
// structure definition named widget2 coming later
int fn(widget2 *p); // OK widget2 need only be *declared* first
// NO
// struct widget2 y; // illegal - has not be defined yet
struct widget2 // defines structure widget2 that *would* take up ~8 bytes
{
int thing1;
int thing2;
} y; // defines variable y of type struct widget2 that *does* take up ~8 bytes
struct widget2 z[10]; // defines global variable z that *does* take up ~80 bytes
另一种看待它的方法是定义类型与定义变量根本不同。类型是在编译时存在的概念,在运行时不占用空间(忽略RTTI)。
C和C ++标准区分了声明和定义,因为除了其他原因之外,你不能有多个不同的定义,但你可以多次声明它。对于变量,定义大致与存储分配一致,但这并不是区分的主要原因。