【问题标题】:QT Static library undefined reference to static variableQT静态库未定义对静态变量的引用
【发布时间】:2016-08-04 21:54:44
【问题描述】:

我在链接我的项目时遇到问题。我正在尝试创建可以在三个不同项目之间使用的共享库。该库将用于解析 XML 文件和处理这些 XML 文件中的对象。

这是受影响的最小示例。库项目由这些文件组成

============= Library.cpp =============
#include "library.h"

Library::Library(QString name){
this->name = name;
}

============= Library.h =============
#ifndef LIBRARY_H
#define LIBRARY_H

 #include <QString>

 class Library
 {

 public:
   Library(QString name);

private:
   static QString name;
};
#endif // LIBRARY_H

============= Library.pro =============
QT       -= gui
TARGET = Library
TEMPLATE = lib
CONFIG += staticlib
SOURCES += library.cpp
HEADERS += library.h
unix {
   target.path = /usr/lib
   INSTALLS += target
}

主应用程序由这些文件组成。

============= main.c =============
#include <QCoreApplication>
#include "library.h"

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   Library lib("MyLib");

   return a.exec();
}

============= Application.pro =============
QT += core
QT -= gui

TARGET = Application
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
SRCDIR = $$IN_PWD/../Library
INCLUDEPATH += $$SRCDIR
SRCDIR = $$IN_PWD/../Library
INCLUDEPATH += $$SRCDIR

LIBDIR = $$IN_PWD/../build-Library-Desktop_Qt_5_5_1_GCC_64bit-Ladění/libLibrary.a
LIBS += $$LIBDIR

这是链接器的输出

g++ -c -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_CORE_LIB -I../Application -I. -I../Library -I../Library -I../../../Qt/5.5/gcc_64/include -I../../../Qt/5.5/gcc_64/include/QtCore -I. -I../../../Qt/5.5/gcc_64/mkspecs/linux-g++ -o main.o ../Application/main.cpp

g++ -Wl,-rpath,/home/mint/Qt/5.5/gcc_64 -Wl,-rpath,/home/mint/Qt/5.5/gcc_64/lib -o Application main.o   /home/mint/Development/test/Application/../build-Library-Desktop_Qt_5_5_1_GCC_64bit-Ladění/libLibrary.a -L/home/mint/Qt/5.5/gcc_64/lib -lQt5Core -lpthread 

/home/mint/Development/test/Application/../build-Library-Desktop_Qt_5_5_1_GCC_64bit-Ladění/libLibrary.a(library.o): In function `Library::Library(QString)':

Makefile:214: recipe for target 'Application' failed

/home/mint/Development/test/build-Library-Desktop_Qt_5_5_1_GCC_64bit-Ladění/../Library/library.cpp:6: undefined reference to `Library::name'
collect2: error: ld returned 1 exit status

当我将 Library.h 中的 static QString 名称更改为非静态变量时,一切正常。那时就可以联动了。我认为,项目文件设置正确,但我缺少什么?

【问题讨论】:

    标签: c++ qt static-libraries


    【解决方案1】:

    在 C++ 中,静态成员应该在类声明之外定义和初始化。

    ============= Library.h =============
    #ifndef LIBRARY_H
    #define LIBRARY_H
    
    #include <QString>
    
    class Library
    {
    public:
        Library(QString name);
    
    private:
        static QString name;// declare
    };
    #endif // LIBRARY_H    
    
    ============= Library.cpp =============
    #include "library.h"
    
    //add this line if name is static member of Library
    QString Library::name;// define and initialize
    
    //you can also initialize it to other value like:
    //QString Library::name = "banana!";
    
    Library::Library(QString name){
        this->name = name;
    }
    

    【讨论】:

    • 虽然此代码可以回答问题,但提供有关它为什么和/或如何回答问题的额外上下文将显着提高其长期价值。请edit你的答案添加一些解释。
    • @JasonMc92 抱歉。我昨天刚睡着了。答案已编辑。感谢您的提醒。
    【解决方案2】:

    在 C++ 中,static 成员变量本质上是全局导出的“类变量”(与其他 static 变量非常不同,在某种意义上甚至相反,您将文件范围变量设为静态以避免 它们被导出为全局变量)。

    在那个.h文件中,你只有变量声明:你声明这种变量存在于某处。

    然而,要让它真正存在,你必须定义它。因此,您需要将此添加到一个 .cpp 文件中:

    QString Library::name = QStringLiteral("initial value");
    

    此外,它是类变量,因此您(可能)不应该在每次创建实例时更改它,因此您的构造函数只是:

    Library::Library() {
    }
    

    如果您想从其他地方初始化它(很可能是main(),要替换构造函数中的代码,只需分配给它:

    Library::name = whatever;
    

    但是,如果您真的想将它作为实例变量(类的每个实例/对象都有自己的副本),那么只需从 .h 文件的 定义 中删除 static .

    此外,对于全局变量(包括static 类变量),您必须注意初始化顺序。它们也是全局变量,会带来所有的麻烦。因此,如果您真的需要它们,请不要使用它们。

    【讨论】:

    • 感谢您的帮助,也感谢您提供有关此主题的理论!实际上我想创建单例,所以静态不会是 QString 类型。 QString 只是为了说明。不管怎样,谢谢你的支持。
    • @user2336793 对于单身人士,您可能应该阅读this question and answers(或谷歌了解其他资源)。有一些有效的方法可以解决单身问题,还有更多的方法会遇到不同类型的问题:)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    相关资源
    最近更新 更多