在名称空间中声明变量,在main中定义它,使其对所有其他文件可见

问题描述 投票:1回答:3

使用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]'
c++ c++11 namespaces global-variables c++14
3个回答
1
投票

#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;

1
投票

您需要定义

在Common.cpp中:

namespace App{
    namespace Common{
        std::string appPath;
    }
}

0
投票

您正在混合定义和赋值,这是变量的两件事:

  • a declaration代表变量x,它告诉编译器在某处存在一个名为x的变量;
  • a definition代表变量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的标题中,否则,您将具有相同变量的多个定义(对于每个包含.cppcommon.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]; }

© www.soinside.com 2019 - 2024. All rights reserved.