4

谁能从 ISO N3242 §3.2 第 4 点解释这个声明

n3242 与 ISO 标准 2003 相比增加的部分:

4如果以要求类类型完整的方式使用类,则翻译单元中只需要一个类的定义。

如果满足以下条件,则类类型T必须是完整的:

  • 声明了类型的非静态类数据成员T(9.2),或
  • T用作新表达式中的对象类型或数组元素类型
  • 类型T是 alignof 表达式 (5.3.6) 的主题,或
  • 异常声明具有类型T、引用T或指向T

谁能解释当前 C++0x 标准草案的这一段?

在这些语句中添加它的实际含义是什么?

任何人都可以借助示例/程序来解释这一点吗?

4

2 回答 2

6

直接来自维基百科

一般来说,一个翻译单元应包含不超过一个任何类类型的定义。在这个例子中,类类型 C 的两个定义出现在同一个翻译单元中。如果一个头文件被同一个源文件包含两次而没有适当的头保护,这通常会发生。

class C {}; // first definition of C
class C {}; // error, second definition of C

在下文中,形成一个指向 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

不止一个定义

在某些情况下,可以有多个类型或模板的定义。由多个头文件和源文件组成的程序通常具有多个类型的定义,但每个翻译单元不超过一个定义。

如果一个程序包含多个类型的定义,那么每个定义必须是等价的。

静态 const 数据成员的定义

在准标准 C++ 中,所有静态数据成员都需要在其类之外进行定义。但是,在 C++ 标准化过程中,决定取消对静态 const 整数成员的这一要求。目的是允许以下用途:

struct C
{
  static const int N = 10;
};
char data[C::N]; // N "used" without out-of-class definition

没有 N 的命名空间范围定义。

尽管如此,如果在程序中使用该成员,1998 C++ 标准的措辞仍然需要定义。这包括出现在任何地方的成员,除了作为 sizeof 或 typeid 的操作数,有效地使上述格式不正确。

这被确定为缺陷,并调整了措辞以允许此类成员出现在需要常量表达式的任何地方,而无需类外定义。这包括数组边界、case 表达式、静态成员初始值设定项和非类型模板参数。

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

但是,在需要整数常量表达式的地方以外的任何地方使用静态 const 整数成员都需要定义

struct C
{
  static const int N = 10;
};

int main()
{
  int i = C::N; // ill-formed, definition of C::N required
}

这一要求将在即将发布的 C++ 标准(俗称 C++0x)中放宽。

于 2011-04-11T13:49:19.170 回答
0

它的意思是,如果您以需要定义的方式使用类类型(并且他们明确列出了使用类的方法),则必须提供该类的确切定义。

如果您不提供定义,那就是错误。如果您在翻译单元中提供多个,则为错误。如果您在多个翻译单元中提供多个定义,则它是未定义的行为。

于 2011-04-11T13:56:04.027 回答