首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >类的全局实例(跨多个文件)

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

Stack Overflow用户
提问于 2016-01-01 06:14:58
回答 3查看 1.8K关注 0票数 0

我正在处理C::B中的一个项目,需要跨多个项目文件使用类的全局实例。(我对头文件和全局类的使用很陌生)

因此,我已经声明、定义、初始化了类和函数:

//复杂。h

代码语言:javascript
运行
复制
class Julia
{
    public:
    double R;
    double I;
    void algorithm();
};
Julia J;

//in complex.cpp

代码语言:javascript
运行
复制
#include "complex.h"
void Julia::algorithm()
{ 
    //fn body here
}

//in main.cpp

代码语言:javascript
运行
复制
#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
}

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

“J”的obj\Debug\complex.o:complex.cpp:(.bss+0x3bf0):多重定义-- obj\Debug\main.o:C:/Users/ShA/Documents/etf_build/main.cpp:20:第一次定义

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

有人能指出代码中可能出现的错误,以及如何找到解决我所得到的错误的方法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-01-01 07:09:35

宣言

代码语言:javascript
运行
复制
Julia J;

标题中有一个J的定义,通过包含标头,您可以在两个翻译单元中定义这个定义:main.cpp翻译单元和complex.cpp翻译单元。

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

正如链接者所看到的,它是对同一事物的两种不同和相互冲突的定义。

一个纯粹的技术解决方案是使J成为一个单例,一个简单的方法是通过函数中的一个static变量(称为“Meyers‘singleton”)来做到这一点:

代码语言:javascript
运行
复制
inline
auto J()
    -> Julia&
{
    static Julia the_object;
    return the_object;
}

上面的技术解决方案是不好的,因为单例就像直接的全局变量一样,引入了复杂的任意通信线路,例如通过您的init函数。

在头文件中将变量声明为extern,并在相应的实现文件中定义变量,这可能是一个更不好的技术解决方案。这特别不好,因为在更一般的情况下,它有使用未初始化变量的风险。这被称为“静态初始化顺序失败”,并在C++常见问题中进行了讨论。

与这些技术解决方案不同,您应该更改设计,让main创建Julia实例。

它可以传递到被调用的函数。

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

票数 1
EN

Stack Overflow用户

发布于 2016-01-01 07:17:47

在复杂.h Julia J;

这是你的错误。任何包含comp.h的源文件都有自己的J版本。这违反了一种定义规则

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

另一方面,如果在多个文件中使用该变量,则所做的操作也是错误的。在这种情况下,complex.h头文件应该将变量J限定为extern关键字。现在,您可以在多个地方引用该全局信息(但请注意静态初始化失败)。您可以在多个地方引用该变量。你需要在一个地方定义这个变量。

票数 1
EN

Stack Overflow用户

发布于 2016-01-14 07:42:42

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

在源文件中放置Julia (Julia J)的一个实例。然后在GetInstance()实现内部(也在源文件中)返回J

Complex.h

代码语言:javascript
运行
复制
class Julia
{
    public:
    double R;
    double I;
    void algorithm();
    static Julia& getInstance();
};

Complex.c

代码语言:javascript
运行
复制
#include "complex.h"
Julia J;
void Julia::algorithm()
{ 
    //fn body here
}
Julia& Julia::getInstance() { return J; }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34554000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档