为什么非静态变量不能驻留在头文件中?

问题描述 投票:0回答:3

举个例子:

// myheader.h
static int myStaticVar = 0;
// If we remove 'static' the compiler will throw linker error.

void DoStuff();

// and myheader.cpp, and main.cpp;  etc

这就是我的解释方式:

静态变量没有外部链接,当我们编译时 如果没有“static”,我们将“包含”静态变量(即 此处为全局)在每个文件中,这会创建重复项并且链接器将 由于不允许多重声明,因此会抛出错误。

有没有更好的方法来解释这个?谢谢。

PS:我们是否应该在头文件中包含静态变量(不谈论成员)?

c++ variables static header
3个回答
13
投票

为什么非静态变量不能驻留在头文件中?

因为它违反了单一定义规则(ODR)
当您包含包含非静态变量的头文件时,该变量的声明将粘贴到包含该变量的每个源文件中。因此,您最终会在同一个翻译单元中拥有多个变量定义,这违反了 ODR,因此链接器会给您带来链接错误。

如何解释头文件中声明的静态变量?

在头文件中声明静态变量时,会在包含头文件的每个翻译单元中创建该变量的副本。

在头文件中声明静态变量不会给您带来多个定义错误,但它无法实现拥有一个全局变量的目的,该全局变量的值在访问它的所有文件之间共享。

您可能认为由于您使用的是全局静态变量,因此它的值将在不同的文件中保留,但如上所述,每个翻译单元都有自己的变量副本,并且它并没有实现您认为要实现的目标.

我们是否应该在头文件中包含静态变量(不谈论成员)?

不,从来没有!

如何声明和定义全局变量?

您需要使用

extern
关键字。

在头文件中添加变量的 extern 声明。定义变量的一个源文件以及引用该变量的所有源文件都应包含标头。 只有一个源文件应该定义变量。另外,只有一个头文件应该声明该变量。

文件名.h

extern int gVariable;  /* Declaration */ 

文件1.cpp

#include "filename.h"  

/* Definition */ 
int gVariable = 37;    

void doSomething(void) 
{ 
    return gVariable++; 
} 

文件2.cpp

#include "filename.h" 
#include <stdio.h>  
void doSomethingWithGlobal(void) 
{     
    printf("Global variable: %d\n", gVariable++); 
} 

1
投票

首先,阅读类似问题的此答案

为了根据您的问题补充答案,这里是:

当您

#include
一个文件(任何文件,
.h
文件是一种常见约定)时,它几乎基本上只是将其复制粘贴到您的代码中。如果头文件中有非静态变量,并且将其包含在两个源文件中,则该变量会复制粘贴到两个源文件中,并且您会收到链接错误,正如我在告诉您阅读的答案中所解释的那样上面。

如果您想在多个源文件之间共享全局变量,您应该这样做:

仅一个源文件中:

type global_var = default_value;

在头文件中:

extern type global_var;

因此,这样,所有源文件都会在一堆源文件中的某处看到一个

global_var
。只有一个源文件实际上包含该变量,并且当发生链接时,所有源文件都将引用
global_var

的一个实例

0
投票

头文件 (.h) 告诉您(声明)定义文件 (.cpp) 将做什么。

打个比喻——头文件就像告诉很多朋友你要做某件事,但实际上你只会做一次。

© www.soinside.com 2019 - 2024. All rights reserved.