c++ - 类有外部链接吗?

标签 c++ class external linkage

我有 2 个文件 A.cpp 和 B.cpp,它们看起来像

A.cpp
----------
class w
{
public:
    w();
};


B.cpp
-----------
class w
{
public:
    w();
};

现在我在某处 ( https://en.cppreference.com/w/cpp/language/static ) 读到类具有外部链接。因此,在构建时我期待一个多重定义错误,但恰恰相反,它像魅力一样工作。但是,当我在 A.cpp 中定义类 w 时,出现重定义错误,这让我相信类具有内部链接。

我是不是漏掉了什么?

最佳答案

正确答案是肯定的,一个类的名称可能有外部链接。以前的答案是错误的和误导性的。您显示的代码是合法且通用的。

C++03 中的类名可以有外部链接也可以没有链接。在 C++11 中,类的名称可能还具有内部链接。

C++03

§3.5 [basic.link]

A name is said to have linkage when it might denote the same object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope

类名可以有外部链接。

A name having namespace scope has external linkage if it is the name of

[...]

— a named class (clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes (7.1.3)

类名不能有链接。

Names not covered by these rules have no linkage. Moreover, except as noted, a name declared in a local scope (3.3.2) has no linkage. A name with no linkage (notably, the name of a class or enumeration declared in a local scope (3.3.2)) shall not be used to declare an entity with linkage.

在 C++11 中,第一个引号发生变化,命名空间范围内的类名现在可能具有外部或内部链接。

An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. A name having namespace scope that has not been given internal linkage above [class names were not] has the same linkage as the enclosing namespace if it is the name of

[...]

— a named class (Clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes (7.1.3);

第二个引用也有变化,但结论是一样的,类名可能没有链接。

Names not covered by these rules have no linkage. Moreover, except as noted, a name declared at block scope (3.3.3) has no linkage. A type is said to have linkage if and only if:

— it is a class or enumeration type that is named (or has a name for linkage purposes (7.1.3)) and the name has linkage; or

— it is an unnamed class or enumeration member of a class with linkage;

这里的一些答案将 C++ 标准中链接的抽象概念与称为链接器的计算机程序混为一谈。 C++ 标准没有赋予符号这个词特殊的含义。符号是链接器在将目标文件组合成可执行文件时解析的内容。形式上,这与 C++ 标准中的链接概念无关。该文档仅在有关字符编码的脚注中解决链接器问题。

最后,您的示例是合法的 C++,并且不违反 ODR。请考虑以下事项。

C.h
----------
class w
{
public:
    w();
};


A.cpp
-----------
#include "C.h"


B.cpp
-----------
#include "C.h"

也许这看起来很眼熟。在评估预处理器指令后,我们留下了原始示例。 Alok Save 提供的维基百科链接甚至将此声明为异常(exception)。

Some things, like types, templates, and extern inline functions, can be defined in more than one translation unit. For a given entity, each definition must be the same.

ODR 规则将内容考虑在内。您展示的内容实际上是翻译单元将类用作完整类型所必需的。

§3.5 [basic.def.odr]

Exactly one definition of a class is required in a translation unit if the class is used in a way that requires the class type to be complete.

编辑 - James Kanze 的后半部分回答正确。

关于c++ - 类有外部链接吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6465325/

相关文章:

python - 如何在 Python 中从继承的类中设置和获取父类属性?

ios - 从 NSObject 类更改 UISwitch 的状态

class - 如何访问/读取 Octave 中的类实例属性?

c++ - 将未知数据类型的元素输入 vector 并传递给函数模板

external - voicexml 中外部语法的结构

javascript - 如何在不增加http请求的情况下包含多个外部javascript文件

javascript - 如何将 C 数组从 C++ 传递到 javascript

C++ UDP套接字错误10045

c++ - 获取最接近 std::set 中给定元素的元素

c++ - 如何检测整个字符串是否未使用 C++ 解析