【问题标题】:Static variable isn't set although visible静态变量虽然可见但未设置
【发布时间】:2012-04-23 04:46:50
【问题描述】:

我有三个文件,一个主 .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 函数来设置它。

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

【问题讨论】:

    标签: c++ oop class object static


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      更改标题以声明变量:

      extern int tryVar;
      

      更改 myClass.cpp 来定义它:

      int tryVar;
      

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

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

      【讨论】:

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

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

        现在来解决您的问题

        1. 静态变量 tryVar 的声明在 myclass.h 中 & 因为 tryVar 的声明在所有函数和类之外,所以该变量是文件范围的,即该变量对文件可见 myclass 的任何位置.h 包含在内,但每个文件都有自己唯一的副本。

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

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

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

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

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

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

        解决方案

        解决方案 1:

        将 tryVar 设为外部,即 tryVar 是全局的,只有一个 tryVar 副本存在

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

        解决方案 2:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-11
          • 2011-11-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-25
          • 1970-01-01
          相关资源
          最近更新 更多