有些来源(书籍,在线资料)解释了extern如下用法:
extern int i; // declaration - has 'extern'
int i = 1; // definition - specified by the absence of 'extern'
Run Code Online (Sandbox Code Playgroud)
并且有些源支持以下语法:
extern int i; // declaration
extern int i = 1; // definition - specified by the equal sign
// Both marked with 'extern'
Run Code Online (Sandbox Code Playgroud)
我的问题是-这是一个ç与C++的区别,或者是一个预ANSI与ANSI的做法?
现在,更实际的问题:
使用第二种语法,我想创建一个全局对象(从每个编译单元可见).构造函数不带参数,因此无论是括号还是等号都不是必需的.
extern MyClass myobject;
Run Code Online (Sandbox Code Playgroud)
现在,编译器如何区分声明和定义?
编辑:回到学校,我习惯了第一种语法(Borland C).后来我使用了一个编译器(可能是GCC的一些古老版本)拒绝编译没有'extern'的定义.这让我感到困惑.
AnT*_*AnT 11
特别是对于您的示例,C和C++在这里没有区别.适用于这两种语言的基本规则是:如果您的声明包含初始值设定项,那么它就是一个定义.期.它无关紧要,无论是否明确extern.如果它有一个初始化程序,那么它就是一个定义.
这意味着,在命名空间范围都extern int i = 1和int i = 1是相等的,即extern在这样的声明是多余的.在C++ extern中,定义在声明的对象时变为非冗余const,因为constC++中的对象默认具有内部链接.例如,使用外部链接extern const int c = 42;定义常量c.
如果声明没有初始化器,那么(并且只有那时)它开始依赖于extern关键字的存在.随着extern它是一个非定义声明.没有extern它是一个定义.(在C中它将是一个暂定的定义,但这与我们背景中的观点不同).
现在,为你的实际问题.要创建全局对象,必须将其声明为
extern MyClass myobject;
Run Code Online (Sandbox Code Playgroud)
(通常在头文件中完成),然后在某个翻译单元中将其定义为
MyClass myobject;
Run Code Online (Sandbox Code Playgroud)
由于构造函数不带参数,因此这是定义对象的唯一方法.(从C++ 11开始,MyClass myobject{};如果您愿意,也可以使用.)
如果你必须为构造函数提供参数(比如说42),你就可以使用它们
MyClass myobject(42);
Run Code Online (Sandbox Code Playgroud)
和
extern MyClass myobject(42);
Run Code Online (Sandbox Code Playgroud)
作为定义,因为初始化器的存在确保它确实被解释为定义.
| 归档时间: |
|
| 查看次数: |
9389 次 |
| 最近记录: |