使用C ++ 14,我试图在存储常用变量(App :: Common)的命名空间中定义一个变量。主要功能应该是设置它的功能,因为它被设置为argv [0]。同时,我需要该变量对所有其他类/文件可见。但是我得到了如下所示的链接器错误。同样,理想情况下,我希望变量是const,其中只有main函数会设置一次。
common.hpp
#pragma once
#include <string>
namespace App{
namespace Common{
extern std::string appPath;
}
}
main.cpp
#include "common.hpp"
#include "client.hpp"
#include <string>
int main() {
App::Common::appPath = argv[0];
}
client.hpp
#include "common.hpp"
class Client {
public:
void printAppPath();
};
client.cpp
#include <iostream>
#include <string>
#include "common.hpp"
#include "client.hpp"
void Client::printAppPath() {
std::cout << App::Common::appPath << std::endl;
}
我通过链接器收到以下错误:
ld: main.o: in function `main':
main.cpp:(.text.startup.main+0x25): undefined reference to `App::Common::appPath[abi:cxx11]'
ld: Client.o: in function `Client::printAppPath()':
Client.cpp:(.text...): undefined reference to `App::Common::appPath[abi:cxx11]'
此
#pragma once
#include <string>
namespace App{
namespace Common{
extern std::string appPath;
}
}
仅包含变量appPath
的声明,而没有其定义。
这里
#include "common.hpp"
#include "client.hpp"
#include <string>
int main() {
App::Common::appPath = argv[0];
}
使用赋值运算符为变量appPath
分配值tp,就好像它已被定义一样。但是实际上它的定义尚不存在。
您可以在Common命名空间的任何封闭命名空间中或该命名空间内部的任何模块中定义变量。例如,您可以在client.cpp中定义它,例如
std::string App::Common::appPth;
您需要定义:
在Common.cpp中:
namespace App{
namespace Common{
std::string appPath;
}
}
您正在混合定义和赋值,这是变量的两件事:
x
,它告诉编译器在某处存在一个名为x
的变量;x
告诉编译器它需要为此变量x
保留一些空间,并且变量x
将位于此位置;对于变量,declaration通常是definition:
void foo() {
int a; // Declaration AND Definition!
}
...除非将变量标记为extern
,否则,因为extern
明确告诉编译器该变量在其他地方defined。您的情况是:
namespace App::Common { // C++17 style
extern std::string appPath;
}
...是declaration,但这是:
namespace App::Common { // C++17 style
std::string appPath;
}
...将是一个定义(也将是一个[[声明),这是:
int main(int argc, char *argv[]) {
App::Common::appPath = std::string(argv[0]);
}
...是。您不应assignment
define
appPath
在诸如common.hpp
的标题中,否则,您将具有相同变量的多个定义(对于每个包含.cpp
的common.hpp
文件一个),并且程序将无法编译。您想要的是程序的单个定义,而获取它的唯一方法是在App::Common::appPath
文件中一次全部定义.cpp
。您可以根据需要在main.cpp
中定义它:#include <string>
#include "common.hpp"
#include "client.hpp"
// Definition:
std::string App::Common::appPath;
int main() {
// Assignment:
App::Common::appPath = argv[0];
}