【发布时间】:2011-06-11 22:00:56
【问题描述】:
下面和这句话下面的代码行是否被视为声明或定义?
extern const int &ri;
【问题讨论】:
标签: c++
下面和这句话下面的代码行是否被视为声明或定义?
extern const int &ri;
【问题讨论】:
标签: c++
这是一个声明——“外部”意味着它存在于其他地方。
【讨论】:
extern 的存在并不一定意味着这不是一个定义。例如,extern const int &ri = 42;是一个定义。说“extern 意味着它生活在其他地方”是不正确的。 extern 表示名称具有外部链接。它没有说明名称背后的实体居住在哪里。它可以存在于此处或其他地方,具体取决于声明的其他细节(例如,初始化器的存在)。
extern 是该声明不是定义所必需的。 +1 表示正确的(如果是微妙的)答案。
extern 的存在,而是初始化器的不存在 使它成为非定义声明。)跨度>
C++03,§3.1,¶2:
声明是一个定义,除非...它包含外部说明符或链接说明,既不是初始化程序也不是函数体...
所以,extern const int &ri;,它包含 extern 说明符而不是初始化器是声明而不是定义。
【讨论】:
首先,声明和定义不是相互排斥的概念。每个定义同时是一个声明(很少有例外)。这意味着提出问题的正确方法是:“这是定义声明还是非定义声明?”。
请注意,我并不是说现在的问题毫无意义。这个问题很好,因为每个人都明白它的真正含义。我只是想把这作为一个介绍性说明。
其次,这里有一个非定义声明,这意味着该声明不是定义(带有 extern 说明符但没有初始化器的引用或对象声明不是定义)。
万一
extern const int &ri = 5;
我们也有一个声明,但这将是一个定义声明(即一个恰好是定义的声明)。
【讨论】:
extern const int &ri = 5;会怎样?
extern const int &ri;
它只是一个没有定义的声明,这表明该变量在其他地方定义。
这样的代码通常在.h文件中找到,它的定义在.cpp文件中找到。如果您将头文件包含在多个文件中,则此方法用于避免多次重定义错误。像这样的:
//lib.h
extern Type object; //declaration Only;
//lib.cpp
#include "lib.h"
Type object = /*some initialization - optional*/; //definition
//A.cpp
#include "lib.h"
Type oA = object;
//B.cpp
#include "lib.h"
Type oB = object;
const在命名空间级别的使用使得被声明或定义的变量具有内部链接,它变得像一个不可变 static变量,它只存在于它自己的翻译单元中.
extern const使变量具有外联性,同时变量是常数。
namespace N
{
const int i = 10; //i has internal linkage
extern const int j = 10; //j has external linkage
}
在这种情况下,extern 用于使变量具有外部链接!
§3.5/3 [basic.link]:
具有命名空间范围的名称 (3.3.5) 如果是名称,则具有内部链接 的
— 对象、引用、函数或 显式的函数模板 声明为静态或,
— 一个物体或 明确声明的引用 const 且均未明确声明 extern 之前也没有声明过 外部链接;或
— 数据成员 一个匿名工会的成员。
【讨论】:
const 是“二级”const,适用于通过引用引用的对象。它不适用于引用本身(事实上,即使尝试这样做也是非法的)。这意味着即使您所说的是正确的,在原始示例中 extern 与 const 无关。即使没有extern,该引用声明也会有外部链接。
除此之外,这几乎可以肯定是对引用的滥用。引用旨在用作函数参数和返回值。您可以创建“引用变量”(我不知道如何描述它们)这一事实似乎是 C++ 语法的一个意外。是的,你可以和他们耍花招,但不,你不应该。
底线 - 如果你有一个不是参数或返回值的引用,你可能做错了什么。除非你真的,真的知道你在做什么,在这种情况下你不会在这里问它,对吗?
【讨论】:
SomeType &r = <some condition> ? <lvalue1> : <lvalue2>;(然后继续使用r)。这是一种广泛使用且非常有用的技术,除非您要说必须为此目的使用 指针。
SomeType &r = <some condition> ? <lvalue1> : <lvalue2>; 好吧,我想我从来没有写过那种代码。一个真实的例子可能会说明为什么会这样。
if 语句的例子......我很难做到这一点,因为语言功能是如此通用 i> 试图为它制作一个具体的例子感觉完全没有意义。假设我有一段代码可以使用左值a 或左值b(取决于某些条件)。所以,我会这样写:为a 或b(取决于条件)创建一个运行时别名r,然后使用r。举个例子吧?
使用extern 表示该对象未在此处定义,而是在其他地方定义。
【讨论】: