简体   繁体   English

为什么要使用extern关键字在命名空间范围内声明变量?

[英]Why should I use the extern keyword to declare variables in a namespace scope?

I am quite new to C++ and am currently taking a short-course on it. 我是C ++的新手,目前正在学习它。 I have some background in Java. 我有一些Java背景知识。

I wish to have a namespace called "Message", that will be used to store unchanging/constant strings that will be used in a variety of different classes throughout my program. 我希望有一个名为“消息”的名称空间,该名称空间将用于存储不变的/不变的字符串,这些字符串将在我的程序中的各种不同类中使用。 (Eg titles, keywords, names, etc). (例如标题,关键字,名称等)。

If all of these strings were in a class, they would be const and static, thus I feel it is best to put them into a namespace rather than a class. 如果所有这些字符串都在一个类中,则它们将是const和static,因此我觉得最好将它们放在命名空间而不是类中。 My current "Message.h" looked a bit like this: 我当前的“ Message.h”看起来像这样:

#ifndef MESSAGE
#define MESSAGE

#include <string>

namespace Message {
    const std::string NAME = "Car";
    const std::string SEPARATE = " | ";
    const std::string COMMAND = "Please enter a 1, 2 or a 3: ";
};

#endif MESSAGE

Until an instructor suggested that I change it to this... 直到老师建议我将其更改为...

Message.h: Message.h:

#ifndef MESSAGE
#define MESSAGE

#include <string>

namespace Message {
    extern const std::string NAME;
    extern const std::string SEPARATE;
    extern const std::string COMMAND;
};

#endif MESSAGE

Message.cpp: Message.cpp:

#include "Message.h"

const std::string Message::NAME = "Car";
const std::string Message::SEPARATE = " | ";
const std::string Message::COMMAND = "Please enter a 1, 2 or a 3: ";

I had little time for clarification from the instructor before the end of a session and it will be quite some-time before I get the opportunity to. 在课程结束之前,我几乎没有时间从讲师那里澄清一下,而且还有很长时间我才有机会参加。 From what I've researched, it has to do with translation-units and more specifically trying to use a variable in a different translation unit. 根据我的研究,它与翻译单元有关,更具体地说,是尝试在其他翻译单元中使用变量。

I understand the general concept of this, but what I can't quite catch is the benefits of using extern in this context? 我了解这个基本概念,但是我不能完全理解在这种情况下使用extern的好处?

Won't the include guards be enough here that the Message:: namespace variables won't be declared/defined more than once? 包含防护在这里是否足够,使得Message ::名称空间变量不会被声明/定义一次以上? Why is the extern keyword recommended in this context and is this purely for the benefits of compile-speed? 为什么在这种情况下推荐使用extern关键字,而这纯粹是出于编译速度的好处?

Both will work just fine (despite the knee-jerk comments the question has gotten). 两者都可以正常工作(尽管问题已经被人们所嘲笑)。 The difference is a bit subtle. 区别有点微妙。

In the first example, every translation unit (think .cpp file) that includes that header will get a copy of each of those three strings. 在第一个示例中,包括该标头的每个翻译单元(如.cpp文件)将获得这三个字符串中每个字符串的副本。 It's okay to do that, because they're marked const , so they are not exported from the translation unit. 可以这样做,因为它们被标记为const ,所以它们不会从翻译单元中导出。 If they were not const you'd have multiple definitions of the same symbol. 如果它们不是const您将具有相同符号的多个定义。

In the second example, there is exactly one copy of each of the three strings. 在第二个示例中,三个字符串中的每个字符串都只有一个副本。 Those copies live in Message.cpp, and will get linked into your executable. 这些副本位于Message.cpp中,并将链接到您的可执行文件中。 Any translation unit that includes Message.h will know about those names, because they're declared in the header, and can use them. 任何包含Message.h的翻译单元都将知道这些名称,因为它们在标头中声明,并且可以使用它们。

For small things like constant int values, the first approach is most common. 对于常量int值之类的小事情,第一种方法是最常见的。 For larger things such as string objects (things that typically require non-trivial initialization), the second approach is most common. 对于较大的事物,例如字符串对象(通常需要非平凡的初始化的事物),第二种方法最为常见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM