我正在处理C::B中的一个项目,需要跨多个项目文件使用类的全局实例。(我对头文件和全局类的使用很陌生)
因此,我已经声明、定义、初始化了类和函数:
//复杂。h
class Julia
{
public:
double R;
double I;
void algorithm();
};
Julia J;
//in complex.cpp
#include "complex.h"
void Julia::algorithm()
{
//fn body here
}
//in 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
}
在构建和运行代码时,我得到了错误--“在这里首先定义”,构建日志显示:
“J”的obj\Debug\complex.o:complex.cpp:(.bss+0x3bf0):多重定义-- obj\Debug\main.o:C:/Users/ShA/Documents/etf_build/main.cpp:20:第一次定义
这是为我的12年级学校项目,我不认为我会被允许使用单身(限制),即使他们似乎是合适的。
有人能指出代码中可能出现的错误,以及如何找到解决我所得到的错误的方法吗?
发布于 2016-01-01 07:09:35
宣言
Julia J;
标题中有一个J
的定义,通过包含标头,您可以在两个翻译单元中定义这个定义:main.cpp
翻译单元和complex.cpp
翻译单元。
链接器不知道它们(原打算是)相同的定义。
正如链接者所看到的,它是对同一事物的两种不同和相互冲突的定义。
一个纯粹的技术解决方案是使J
成为一个单例,一个简单的方法是通过函数中的一个static
变量(称为“Meyers‘singleton”)来做到这一点:
inline
auto J()
-> Julia&
{
static Julia the_object;
return the_object;
}
上面的技术解决方案是不好的,因为单例就像直接的全局变量一样,引入了复杂的任意通信线路,例如通过您的init
函数。
在头文件中将变量声明为extern
,并在相应的实现文件中定义变量,这可能是一个更不好的技术解决方案。这特别不好,因为在更一般的情况下,它有使用未初始化变量的风险。这被称为“静态初始化顺序失败”,并在C++常见问题中进行了讨论。
与这些技术解决方案不同,您应该更改设计,让main
创建Julia
实例。
它可以传递到被调用的函数。
如果您发现它传递给了许多函数,特别是作为第一个参数,那么这些函数可能应该是Julia
类的成员函数,或者您应该为此引入一个新的类。
发布于 2016-01-01 07:17:47
在复杂.h
Julia J;
这是你的错误。任何包含comp.h的源文件都有自己的J
版本。这违反了一种定义规则。
如果使用全局变量J
的惟一位置是在int main
中,则没有理由将该变量设置为全局变量。使J
成为主函数中的局部变量。声明一个只在一个地方使用的全局变量是错误的。
另一方面,如果在多个文件中使用该变量,则所做的操作也是错误的。在这种情况下,complex.h
头文件应该将变量J
限定为extern
关键字。现在,您可以在多个地方引用该全局信息(但请注意静态初始化失败)。您可以在多个地方引用该变量。你需要在一个地方定义这个变量。
发布于 2016-01-14 07:42:42
在您的static Julia& GetInstance()
声明中(在头文件中)放置一个class Julia
函数。
在源文件中放置Julia
(Julia 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; }
https://stackoverflow.com/questions/34554000
复制相似问题