静态变量未设置,尽管可见

Static variable isn't set although visible

本文关键字:变量 设置 静态      更新时间:2023-10-16

我有三个文件,一个主文件.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();
};

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

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

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

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

//myClass.h
extern int tryVar;
//myClass.cpp
int tryVar = 0;  //definition needed for extern variable

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

如果要从多个翻译单元(.cpp文件)访问变量,则它不应是静态的。相反,它应该在标头中使用 extern 声明,然后在一个翻译单元中定义。查看过去的堆栈溢出问题 C 中的外部变量是什么?

更改标头以声明变量:

extern int tryVar;

更改 myClass.cpp 来定义它:

int tryVar;

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

一般来说,如果你在标头中的全局(即非成员)函数或变量上使用static,你可能做错了。(不过,对标头中的成员函数和变量使用 static 是可以的。仅在.cpp文件中使用全局static

  1. 当在函数和类之外声明静态变量时,变量具有文件范围,在这种情况下,tryVar对于包含myclass.h的文件是唯一的,因此对于我们的问题,我们有两个唯一的tryvAr版本,一个用于myclass.cpp另一个用于main.cpp

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

现在来谈谈你的问题

    静态变量tryVar的声明在myclass.h
  1. 中,由于tryVar的声明在所有函数和类之外,变量是文件scopic 的,即,该变量对包含myclass.h的文件可见,但每个文件都有自己唯一的副本。

  2. tryVar = 23;//为什么这不起作用?

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

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

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

    这返回零,因为你正在尝试打印myClass独有的tryVar.cpp并且由于你没有调用setfunction,编译器initiaLIze变量为零,这就是为什么你得到零,

    尝试在主文件中调用 myClass::setTryVar() 函数,然后再打印 myClass.cpp 文件唯一的 tryVAr。

溶液

解决方案 1 :

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

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

解决方案 2:

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