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

时间:2012-04-10 21:06:32

标签: c++ oop class object static

我有三个文件,一个主.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文件中。然后为什么静态变量不可见?

3 个答案:

答案 0 :(得分:8)

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

要完成您想要的任务,您需要一个extern变量:

//myClass.h
extern int tryVar;

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

答案 1 :(得分:5)

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

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

更改标题以声明变量:

extern int tryVar;

更改 myClass.cpp 以定义它:

int tryVar;

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

一般来说,如果您在标题中对全局(即非成员)函数或变量使用static,那么您可能做错了。 (但是对标题中的成员函数和变量使用static很好。)仅在.cpp文件中使用全局static

答案 2 :(得分:1)

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

  2. 声明静态变量时&amp;未初始化编译器会自动将变量初始化为零。

  3. 现在出现问题

    1. 静态变量tryVar的声明在myclass.h&amp;因为tryVar的声明超出了所有功能和范围。类,变量是文件scopic即,变量对于包含myclass.h的文件是可见的,但每个文件都有自己唯一的副本。

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

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

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

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

      这将返回零,因为您正在尝试打印myClass.cpp&amp;的唯一的tryVar。因为你没有调用setfunction,所以编译器initiaLIzes变量为零,这就是为什么你得零,

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

    4. <强>解决方案

      解决方案1:

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

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

      解决方案2:

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