1Us*_*ser 4 c++ standards one-definition-rule c++11
任何人都可以从ISON3242§3.2第4点解释这一说法
与ISO Standard 2003相比,n3242的附加部分:
4如果以需要类类型完整的方式使用类,则在翻译单元中需要一个类的正确定义.在以下情况下,类类型
T必须完整:
T声明类型的非静态类数据成员(9.2),或T用作new-expression中的对象类型或数组元素类型- 类型
T是alignof表达式的主语(5.3.6),或- 异常声明具有类型
T,引用T或指向T
任何人都可以解释当前C++ 0x标准草案的这一段吗?
在这些陈述中添加这个的实际含义是什么?
任何人都可以借助示例/程序来解释这一点吗?
小智 6
通常,翻译单元应包含任何类类型的不超过一个定义.在此示例中,类类型C的两个定义出现在同一转换单元中.如果头文件由相同的源文件包含两次而没有适当的标头保护,则通常会发生这种情况.
class C {}; // first definition of C
class C {}; // error, second definition of C
Run Code Online (Sandbox Code Playgroud)
在下面,形成指向S的指针或定义一个引用S的函数是合法结构的例子,因为它们不需要S的类型是完整的.因此,不需要定义.
定义类型为S的对象,带有S类参数的函数或在sizeof表达式中使用S的函数是S必须完成的上下文的示例,因此需要定义.
struct S; // declaration of S
S * p; // ok, no definition required
void f(S&); // ok, no definition required
void f(S); // ok, no definition required
S f(); // ok, no definition required
S s; // error, definition required
sizeof(S); // error, definition required
Run Code Online (Sandbox Code Playgroud)
不止一个定义
在某些情况下,类型或模板可以有多个定义.由多个头文件和源文件组成的程序通常具有多个类型的定义,但每个翻译单元不超过一个定义.
如果程序包含多个类型的定义,则每个定义必须是等效的.
static const data members的定义
在预标准C++中,所有静态数据成员都需要在其类之外定义.但是,在C++标准化过程中,决定解除静态const积分成员的这一要求.目的是允许以下用途:
struct C
{
static const int N = 10;
};
char data[C::N]; // N "used" without out-of-class definition
Run Code Online (Sandbox Code Playgroud)
没有N的命名空间范围定义.
尽管如此,如果该成员在该计划中使用,1998 C++标准的措辞仍然需要一个定义.这包括成员出现在任何地方,除了作为sizeof或typeid的操作数,有效地使上述形式错误.
这被确定为缺陷,并且调整了措辞以允许这样的成员出现在需要常量表达的任何地方,而不需要类外定义.这包括数组边界,大小写表达式,静态成员初始值设定项和非类型模板参数.
struct C
{
static const int N = 10;
static const int U = N; // Legal per C++03
};
char data[C::N]; // Legal per C++03
template<int> struct D;
template<> struct D<C::N> {}; // Legal per C++03
Run Code Online (Sandbox Code Playgroud)
但是,除了需要使用整数常量表达式之外,在任何地方使用静态const积分成员都需要定义
struct C
{
static const int N = 10;
};
int main()
{
int i = C::N; // ill-formed, definition of C::N required
}
Run Code Online (Sandbox Code Playgroud)
即将推出的C++标准(通俗地称为C++ 0x)将放宽此要求.