4

Can anyone explain this statement from ISO N3242 §3.2, 4th point

The added part of n3242 when compare to ISO Standard 2003 :

4 Exactly one definition of a class is required in a translation unit if the class is used in a way that requires theclass type to be complete.

A class type T must be complete if:

  • a non-static class data member of type T is declared (9.2), or
  • T is used as the object type or array element type in a new-expression
  • the type T is the subject of an alignof expression (5.3.6), or
  • an exception-declaration has type T, reference to T, or pointer to T

Can anyone explain this paragraph of the current C++0x standard draft?

What is the actual meaning of adding this in these statement?

Can any one explain this with the help of an example/program?

4

2 に答える 2

6

ウィキペディアから直接

一般に、翻訳単位にはクラス型の定義が 1 つしか含まれません。この例では、クラス型 C の 2 つの定義が同じ翻訳単位に含まれています。これは通常、ヘッダー ファイルが適切なヘッダー ガードなしで同じソース ファイルによって 2 回インクルードされた場合に発生します。

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

複数の定義

場合によっては、型またはテンプレートの定義が複数存在することがあります。複数のヘッダー ファイルとソース ファイルで構成されるプログラムには、通常、1 つの型の定義が複数ありますが、翻訳単位ごとに複数の定義はありません。

プログラムに 1 つの型の定義が複数含まれている場合、各定義は同等でなければなりません。

static const データ メンバの定義

標準化前の C++ では、すべての静的データ メンバーはクラス外で定義する必要がありました。ただし、C++ 標準化プロセス中に、static const 整数メンバーに対するこの要件を解除することが決定されました。その意図は、次のような使用を許可することでした。

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

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

ただし、整数定数式が必要な場所以外の場所で static const 整数メンバーを使用するには、定義が必要です。

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

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

この要件は、口語的に C++0x と呼ばれる次期 C++ 標準で緩和される予定です。

于 2011-04-11T13:49:19.170 に答える
0

それが言っているのは、定義を必要とする方法でクラスタイプを使用する場合(およびクラスを使用する方法を明示的にリストしている場合)、そのようなクラスの定義を1つだけ提供する必要があるということだけです。

定義を指定しないとエラーになります。翻訳単位に複数指定するとエラーになります。複数の翻訳単位にわたって複数の定義を提供すると、未定義の動作になります。

于 2011-04-11T13:56:04.027 に答える