我在链接项目时遇到问题。我正在尝试创建可以在三个不同项目之间使用的共享库。该库将用于解析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名称更改为非静态变量时,一切正常。它可以联系起来。我认为,项目文件设置正确,但我缺少什么?
答案 0 :(得分:1)
在C ++中,static
成员变量基本上是全局导出的&#34;类变量&#34; (因此与其他static
变量非常不同,在某种意义上,即使相反,您也可以将文件范围变量设置为静态,以便避免将它们导出为全局变量。)
在那个.h文件中,你只有变量声明:你声明这种变量存在于某个地方。
但是,要实际让它存在,你必须定义它。因此,您需要将其添加到一个.cpp
文件中:
QString Library::name = QStringLiteral("initial value");
此外,它是类变量,因此您(可能)每次创建实例时都不应该更改它,因此您的consturctor将只是:
Library::Library() {
}
如果你想从其他地方(很可能main()
)初始化它,要替换构造函数中的代码,只需分配给它:
Library::name = whatever;
但是,如果您确实希望将其作为实例变量(类的每个实例/对象都有自己的副本),那么只需从中删除定义中的static
即可。 h档。
此外,对于全局变量(包括static
类变量),您必须注意初始化顺序。它们也是全局变量,可带来所有麻烦。所以,如果你真的需要他们,不要使用它们。
答案 1 :(得分:0)
在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;
}