C ++变量由2个文件共享

时间:2012-03-29 16:26:12

标签: c++ class variables pointers share

我有4个文件:

  • shared.h
  • 的main.cpp
  • something.h
  • something.cpp

shared.h:

#ifndef SHARED_H
#define SHARED_H

int* sth;

#endif

something.h:

#ifndef SOMETHING_H
#define SOMETHING_H

class foo
{
   public:
      void printVar();
};

#endif

something.cpp:

#include <iostream>
#include "something.h"
#include "shared.h"

using namespace std;

void foo::printVar()
{
    cout<<"Foo: "<<*sth<<endl;
};

main.cpp中:

#include <cstdlib>
#include <iostream>
#include "shared.h"
#include "something.h"

using namespace std;

int main(int argc, char *argv[])
{
    sth=new int(32);

    foo x;
    cout<<"Main: "<<*sth<<endl;
    x.printVar();

    system("PAUSE");
    return EXIT_SUCCESS;
}

编译器返回* sth;

的多重定义

我在* sth中添加了静态修饰符并编译,但崩溃了。我更改了打印以打印指针的地址,我已经返回了程序:

Main: 0x3e0f20
Foo: 0

为什么没有分配foo的指针?我想在main中只分配一次,然后在其他文件中共享...我该怎么做?它是extern修饰符吗?

任何回复的Thanx。

5 个答案:

答案 0 :(得分:5)

在shared.h中你想说:

extern int* sth;

承诺编译器存在于某处。

然后在一个(只有一个).cpp文件中你需要写:

int* sth;

使其真正存在。一般来说,您可能想阅读the difference between declaration and definition。根据经验,您只想在头文件中声明事物,而不是定义它们。

当你以前写过static时,你说每个文件中都存在一个同名的变量,但每个文件都是“本地的”,即main.cpp中的sth不是与something.cpp中的sth相同。

答案 1 :(得分:4)

是的,请使用extern。将extern int* sth;放入标题中,然后将一个放入int* sth;的源文件中。

extern告诉编译器和链接器实际的变量/函数定义在另一个编译单元(即另一个源文件)中。

答案 2 :(得分:2)

您需要在标头中将sth标记为extern以使其成为声明,并在其中一个中为其提供定义 cpp文件。否则,变量在每个包含标题的编译单元中声明,这不是您要查找的效果。

P.S。我假设您知道为什么全局变量不好,对吗?

答案 3 :(得分:2)

我有4个文件 ”。

让我在那里阻止你。我同意你有四个文件,但这并不是真的相关。您有两个 翻译单元。翻译单元是输入编译器的文本量。您的翻译单元,我们称之为 MAIN SOMETHING ,分别包含预处理文件main.cppsomething.cpp的结果。

预处理后,每个翻译单元都包含一行int *sth;此行声明并定义变量sth

单定义规则要求您在整个程序中只有sth的一个(不多于,不少于)定义。为了实现这一目标,您必须在一个翻译单元中只有一个源代码行int *sth;,并且根据需要只需要extern int *sth;个。{/ p>

在您的情况下,我会将int *sth;放在MAIN中,extern int *sth;放在SOMETHING中。此外,你可以拥有尽可能多的extern int *sth;副本 - 它们不会伤害任何东西。

现在,回到你的四个文件。您应该将extern int *sth;放入shared.h。这意味着MAIN和SOMETHING都会有extern行。您还应将int *sth;放入main.cpp,以便MAIN具有定义。

你有:MAIN和SOMETHING都有extern行,所以他们都指的是同一个变量。 MAIN也有一个定义。所以sth变量只有其中一个。

<小时/> 除了:为什么static int *sth;shared.h做错了什么?

因为两个翻译单元中的每一个都看到了他们自己的static声明。 static声明减少了声明名称与单个翻译单元的链接。

答案 4 :(得分:1)

您不希望将其设为静态全局,因为它会在每个翻译单元中创建本地sth,而您只将其分配为一个。这就是它在Foo::printVar中崩溃的原因,因为它是一个未初始化的指针。

您希望在共享标头中将其声明为extern int* sth;,然后将int* sth;放在main之前或至少在其中一个位置使用之前。

实际上,如果你真的需要一个全局可访问的对象,在堆上分配,并且你想要共享它,那么它可能会更好extern std::shared_ptr<int> sth;。在其中一个CPP文件中将其定义为std::shared_ptr<int> sth;,并调用std::make_shared进行分配。这样,当使用它的最后一个对象超出范围时,将自动处理释放内存。