1

我有三个文件,一个主 .cpp 文件:

#include <stdio.h>
#include "myClass.h"



int main()
{

    myClass mvar;

    tryVar = 23; // why does this not work?

    printf("%d ", mvar.readTryVar()); // This writes out 0, why??

    return 0;
}

一个 myClass.cpp 文件

#include "myClass.h"


myClass::myClass(void)
{
}


myClass::~myClass(void)
{
}

void myClass::setTryVar()
{
    tryVar = 23334;
}

int myClass::readTryVar()
{
    return tryVar;
}

和一个 myClass.h 文件

#pragma once

static int tryVar;

class myClass
{
public:
    myClass(void);
    ~myClass(void);


    void setTryVar();

    int readTryVar();
};

它们是非常简单的文件,但是我不明白为什么没有在 main 函数中设置静态变量,我需要通过 myClass 函数来设置它。

我认为我不太清楚“翻译单元”是如何创建的,我知道“包含”指令只是在实际编译之前将头文件的内容复制到 .cpp 文件中。那为什么不是静态变量可见吗?

4

3 回答 3

8

static有多重含义。在 a 之外class,它声明了一个对每个翻译单元都是唯一的变量,因此main.cppmyClass.cpp自己的副本。

为了完成你想要的,你需要一个extern变量:

//myClass.h
extern int tryVar;

//myClass.cpp
int tryVar = 0;  //definition needed for extern variable
于 2012-04-10T21:10:35.823 回答
5

从广义上讲,您可以将每个 .cpp 文件视为一个翻译单元。其他所有内容都包含在其中#include。因此,由于您的 .cpp 文件都包含myClass.h,因此它们定义了一个名为 的静态变量tryVar。您有两个同名的变量,每个代码文件都读取和写入自己的副本。他们看不到对方的副本。

如果要从多个翻译单元(.cpp 文件)访问一个变量,那么它不应该是静态的。相反,它应该extern在头文件中声明,然后在一个翻译单元中定义。查看过去的 Stack Overflow 问题What is extern variables in C?

更改标题以声明变量:

extern int tryVar;

更改myClass.cpp以定义它:

int tryVar;

通过这两个更改,您可以在整个程序中读取和写入相同的变量。

一般来说,如果您在 header 中static使用全局(即非成员)函数或变量,您可能做错了。(不过,在头文件中使用成员函数和变量很好。)仅在 .cpp 文件中使用全局。staticstatic

于 2012-04-10T21:10:35.270 回答
1
  1. 当在函数和类之外声明静态变量时,该变量具有文件范围,在这种情况下,tryVar 对于包含 myclass.h 的文件是唯一的,因此对于我们的问题,我们有两个唯一版本的 tryvAr 一个用于 myclass。 cpp & other for main.cpp

  2. 当声明静态变量且未初始化时,编译器会自动将该变量初始化为零。

现在来解决你的问题

  1. 静态变量 tryVar 的声明在 myclass.h 中 & 由于 tryVar 的声明在所有函数和类之外,因此该变量是文件范围的,即该变量对包含 myclass.h 的文件可见,但每个文件有自己独特的副本。

  2. 尝试变量 = 23; // 为什么这不起作用?

    这实际上有效,但不是您想要的方式,因为您要打印的是 tryVar 变量,该变量可通过类 mycalss 的对象对 myclass.cpp 可用(唯一),

    直接在主文件中打印 tryVar ,您可以看到输出为 23 。

  3. printf("%d", mvar.readTryVar()); // 这写出 0,为什么?

    这将返回零,因为您正在尝试打印 myClass.cpp 独有的 tryVar 并且由于您没有调用 setfunction 编译器将变量初始化为零,这就是您得到零的原因,

    在打印 myClass.cpp 文件特有的 tryVAr 之前,尝试在主文件中调用 myClass::setTryVar() 函数。

解决方案

解决方案1:

使 tryVar extern 即 tryVar 是全局的,只有一个 tryVar 副本存在

缺点:此解决方案的问题是您无法控制变量

解决方案2:

将 tryVar 作为类的静态数据成员并在 myClass.cpp 中定义它,通过这种方式,您可以控制变量的可见性

于 2013-09-29T14:10:19.747 回答