使用静态成员时的链接器错误

Posted

技术标签:

【中文标题】使用静态成员时的链接器错误【英文标题】:Linker error when using static members 【发布时间】:2011-12-23 04:20:14 【问题描述】:

我在 Mac OS X 上使用 Qt 4.7 和 Cmake 2.8.3 以及 g++ 4.2.1。

在我的一个文件中使用静态或全局变量时,我遇到了一个奇怪的链接器错误。 这是错误:

ld: duplicate symbol ColorTrail::calculateColorUniformLocation        in CMakeFiles/GLBall.dir/src/DesktopMain.cpp.o and CMakeFiles/GLBall.dir/src/ColorTrail.cpp.o
collect2: ld returned 1 exit status

calculateColorUniformLocation 是 ColorTrail 类的静态成员...但它甚至根本没有在 DesktopMain.cpp 中使用!

这是我尝试过的: 重命名变量并不能解决问题。 将变量移出类并使其成为普通的全局变量也不能解决它

文件 ColorTrail.h:

#ifndef COLORTRAIL
#define COLORTRAIL 9

#include "GlobalConstants.h"
#include <vector>
using namespace std;


class ColorTrail

private:
    //note that this is NOT a Q_OBJECT

    static GLint calculateColorUniformLocation;

    //omitted for brevity
;

GLint ColorTrail::calculateColorUniformLocation;


#endif

DesktopMain.cpp 使用 ColorTrail 类,但不是静态的,从不引用变量。

有人知道 Qt 出了什么问题/遇到过类似的问题吗?

【问题讨论】:

就像 Naveen 说的,移动 GLint ColorTrail::calculateColorUniformLocation;到 .cpp 文件 What does it mean to have an undefined reference to a static member? 的可能重复项 【参考方案1】:

你需要在cpp文件中定义静态变量,而不是在头文件中。如果你在头文件中定义它,每个包含这个头文件的 cpp 文件都会得到它自己的副本,因此链接器会抱怨重复的符号。

【讨论】:

【参考方案2】:

Static data members must be explicitly defined in exactly one compilation unit

查看此链接:http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

【讨论】:

以上是关于使用静态成员时的链接器错误的主要内容,如果未能解决你的问题,请参考以下文章

类加载器实例化时的顺序

类加载器实例化时的顺序

Qt5 - Windows:不一致的 dll 链接错误和 dllimport 静态数据成员的定义不允许

Java类的各种成员初始化顺序如:父子类继承时的静态代码块,普通代码块,静态方法,构造方法,等先后顺

c2797 未实现成员初始化器列表或非静态数据成员初始化器内的列表初始化

在初始化程序错误中只能访问静态成员