任何人都可以解释当前C++ 0x标准草案的这一段吗?

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)将放宽此要求.