类的全局实例(跨多个文件)

时间:2016-01-01 06:14:59

标签: c++ codeblocks

我正在使用C :: B中的一个项目,需要在多个项目文件中使用类的全局实例。 (我对头文件和全局类的使用不熟悉)
我已声明,定义,初始化类和函数:

//在complex.h中

class Julia
{
    public:
    double R;
    double I;
    void algorithm();
};
Julia J;

//在complex.cpp中

#include "complex.h"
void Julia::algorithm()
{ 
    //fn body here
}

//在main.cpp

#include"complex.h"
int main()
{
    //calls initialize() and display()
}

void initialize()
{
    //...some code(irrelevant)
    cin>>J.R>>J.I;
}

void display()
{
    J.algorithm();
    //some more (irrelevant) code
}

在构建和运行代码时,我得到错误 - "首先在这里定义"并且构建日志显示:

obj \ Debug \ complex.o:complex.cpp :(。bss + 0x3bf0):`J'的多重定义 obj \ Debug \ main.o:C:/Users/ShA/Documents/etf_build/main.cpp:20:首先在这里定义

[这是我的12年级学校项目,我不认为我会被允许使用单身人士(限制),即使他们似乎是合适的。 ]

有人可以指出代码中可能存在的错误以及如何找到我遇到的错误的解决方案吗?

3 个答案:

答案 0 :(得分:1)

声明

Julia J;
标头中的

J定义,并且通过包含标题,您可以在两个翻译单元中使用此定义:main.cpp翻译单元和{{ 1}}翻译单位。

链接器不知道它们(原本打算)是相同的定义。

当链接器看到它时,它是同一事物的两个独立且相互冲突的定义。

一个纯粹的技术解决方案是让complex.cpp成为一个单例,一个简单的方法就是通过函数中的J变量来实现,这个变量称为“迈耶斯的单身人士”:

static

上面的技术解决方案是不合适的,因为单一例如直接全局变量引入了复杂的任意通信线路,例如,通过您的inline auto J() -> Julia& { static Julia the_object; return the_object; } 功能。

在标题中将变量声明为init并在相应的实现文件中定义变量,还有一种更有用的技术解决方案。这是额外的好处,因为在更一般的情况下,它存在使用未初始化变量的风险。这被称为“静态初始化顺序惨败”,并在C ++ FAQ中讨论。

您应该更改设计并让extern创建main实例,而不是这些技术解决方法。

它可以传递给调用函数。

如果你发现它被传递给了许多函数,特别是作为第一个参数,那么这些函数可能应该是Julia类的成员函数,或者你应该为此引入一个新类

答案 1 :(得分:1)

  

in complex.h

     

Julia J;

这是你的错误。 #includes complex.h的任何源文件都有自己的J版本。这违反了one definition rule

如果您使用全局变量J的唯一位置在int main中,则没有理由将该变量设为全局变量。在主函数中使J成为局部变量。声明仅在一个地方使用的全局变量是错误的。

另一方面,如果您在多个文件中使用该变量,那么您所做的也是错误的。在这种情况下,您的complex.h标头文件应使用J关键字限定变量extern。现在,您可以在多个位置引用该全局(但要注意static initialization fiasco)。您可以在多个位置引用该变量。您需要在一个地方定义该变量。

答案 2 :(得分:0)

static Julia& GetInstance()声明中(在标题文件中)放置一个class Julia函数。

JuliaJulia J)的实例放在源文件中。然后在GetInstance()实现(也在源文件中)内,返回J

Complex.h

class Julia
{
    public:
    double R;
    double I;
    void algorithm();
    static Julia& getInstance();
};

complex.c里

#include "complex.h"
Julia J;
void Julia::algorithm()
{ 
    //fn body here
}
Julia& Julia::getInstance() { return J; }