D 1.0   D 2.0
About Japanese Translation

Last update Tue Nov 9 13:50:04 2010

属性

AttributeSpecifier:
    Attribute :
    Attribute DeclarationBlock

Attribute:
    LinkageAttribute
    AlignAttribute
    Pragma
    deprecated
    ProtectionAttribute
    static
    final
    synchronized
    override
    abstract
    const
    auto
    scope


DeclarationBlock:
    DeclDef
    { }
    { DeclDefs }

属性とは、一つ、もしくは複数の宣言を修飾するものです。 一般的な構文は:

attribute declaration;		// かかっている宣言に影響

attribute:			// 現在のスコープが終わるまでの
					// 全ての宣言に影響
    declaration;
    declaration;
    ...

attribute			// ブロック内の全ての宣言に影響
{
    declaration;
    declaration;
    ...
}

else節を加えることのできる属性では:

attribute
    declaration;
else
    declaration;

attribute			// ブロック内の全ての宣言に影響
{
    declaration;
    declaration;
    ...
}
else
{
    declaration;
    declaration;
    ...
}

リンケージ属性

LinkageAttribute:
	extern
	extern ( LinkageType )

LinkageType:
	C
	C++
	D
	Windows
	Pascal
	System

C やシステムのAPI関数との互換性は重要ですから、 Dはそれらを簡単に呼び出す手段を提供しています。 LinkageType は大文字小文字を区別し、 実装によって拡張されることを想定しています(予約語ではありません)。 CD は必須ですが、 その他は実装によります。 C++ は将来のために予約されています。 System は Windows 環境では Windows と同じ意味で、 それ以外の環境では C と同じ意味になります。 実装ノート: Win32向けのコンパイラは WindowsPascal をサポートすべきです。

C の関数呼び出し規約を指定するには:

extern (C):
	int foo();	// foo() は C の呼び出し規約で呼ばれる

Dの呼び出し規約ならば:

extern (D):

あるいは:

extern:

Windows API の呼び出し規約は:

extern (Windows):
    void *VirtualAlloc(
    void *lpAddress,
    uint dwSize,
    uint flAllocationType,
    uint flProtect
    );

アラインメント属性

AlignAttribute:
	align
	align ( IntegerLiteral )

構造体メンバのアラインメントを指定します。 align と単独で書くと、 その環境のCコンパイラでのデフォルト値へ設定されます。 Integer を指定すると、そのバイト境界へとメンバを整列します。

協調するCコンパイラと挙動を揃えるために、align 属性はしばしば不思議な動作をします。例えばDigital Mars C++の場合こうなります:

struct S
{   align(4) byte a;	// オフセット 0 に配置
    align(4) byte b;	// オフセット 1 に配置
}

AlignAttribute は、CのABIとの互換のために用意されており、 プラットフォーム間のバイナリ互換性のために用意されているものではありません。 そちらの目的には、構造体に明示的に詰め物を入れます:

align (1) struct S
{   byte a;	// オフセット 0 に配置
    byte[3] filler1;
    byte b;	// オフセット 4 に配置
    byte[3] filler2;
}

1を指定すると整列は行われず、 全てのメンバがきっちり詰め込まれます。

NewExpression で割り付けたメモリへの参照やポインタは、 size_tの倍数以外のバイト境界に揃えるのは避けてください。 ガベージコレクタは、GCの割り当てたオブジェクトへの参照やポインタは size_tバイト境界に存在すると仮定して動作しています。 そうなっていない場合、 動作は未定義です。

AlignAttribute は、構造体や構造体メンバ以外に宣言された場合には、 無視されます。 クラスのメンバに適用されるかどうかは実装依存です。

AlignAttribute は、struct、union、class、 あるいは関数スコープに入るときにデフォルトに戻され、 スコープを抜けると元に戻ります。基底クラスからアラインメントが継承されることもありません。

deprecated属性

ライブラリには、 後方互換性のために非推奨の機能を残す必要が しばしば生じます。このような機能の制限には 'deprecated' と印をつけておきます。すると、 コンパイラスイッチの設定によって、 非推奨の機能を使うコードをエラーにすることが可能になります:

deprecated
{
	void oldFoo();
}

実装ノート: コンパイラは、 非推奨機能のコンパイルの際に警告するかしないか、 を指定するスイッチを用意しておくべきです。

アクセス保護属性

ProtectionAttribute:
    private
    package
    protected
    public
    export

アクセス保護属性は、 private, package, protected, public, export, のいずれか一つです。

private は、同じクラスのメンバのみが参照できる、 あるいは同じモジュールのクラス/関数のみが参照できることを示します。 private メンバをオーバーライドすることはできません。 モジュールのメンバを private と宣言するのは、 C での static 宣言と同等です。

package は、モジュールは違っても同じパッケージに属するコードからの アクセスは許可するようにprivateを拡張したものです。 これは、モジュールがネストしたパッケージの中にある場合は、 最も内側のパッケージについてのみ適用されます。

protected は、同じクラスかその派生クラスのメンバ、 または同じモジュールに属するコード からのみからのみ参照できることを示します。 派生クラスのメンバ関数から protected なインスタンスメンバへアクセスする場合、 そのメンバ関数の 'this' オブジェクトに属するメンバについてのみ、アクセスが可能です。 モジュールのメンバを protected とするコードは不正です。

public は、同じ実行ファイル中の全てのコードからアクセス可能なことを示します。

export は、実行ファイルの外からもアクセスできることを示します。 DLLから関数定義をエクスポートする、 というのと似ています。

const属性

const

const は、コンパイル時に評価できる定数につける属性です。 例えば:

const int foo = 7;

const
{
    double bar = foo + 6;
}

初期化子のないconst宣言は、 コンストラクタ(インスタンス変数の場合)か、静的コンストラクタ (クラス変数やモジュール変数の宣言の場合)での初期化が必須です。

const int x;
const int y;

static this()
{
    x = 3;	// ok
    // エラー: yが初期化されていない
}

void foo()
{
    x = 4;	// エラー。x はconstで、ここは静的コンストラクタ内ではない
}

class C
{
    const int a;
    const int b;
    static const int c;
    static const int d;

    this()
    {   a = 3;		// ok
	a = 4;		// ok。多重の初期化は許されている
	C p = this;
	p.a = 4;	// エラー。このインスタンスのメンバではない
	c = 5;		// エラー。静的コンストラクタで初期化すべき
	// エラー, bが初期化されていない
    }

    this(int x)
    {
	this();		// ok, コンストラクタの転送
    }

    static this()
    {
	c = 3;		// ok
	// エラー, dが初期化されていない
    }
}

初期化子もコンストラクタもないconstモジュール変数の宣言は、 エラーにはなりません。これは、 宣言のためのみに使ってリンクはしないで、 実装はリンクされる他のモジュールに書く、という技法をサポートするためです。

override属性

override

override は、仮想関数に適用する属性です。 これは、 そのメンバ関数は基底クラスの同名同引数の関数をオーバーライドしているのだ、 という宣言になります。override属性は、基底クラスの仮想関数の引数を変更して、 全ての派生クラスの実装を変更しなくてはならない、 という状況などに便利です。

class Foo
{
    int bar();
    int abc(int x);
}

class Foo2 : Foo
{
    override
    {
	int bar(char c);	// エラー。 Foo には bar(char) という関数はない
	int abc(int x);		// ok
    }
}

static属性

static

static 属性は関数もしくはデータに適用されます。 これは、その宣言が特定のインスタンスに関するものではなく、 ある型に関するものである、という意味になります。 言い方を変えると、this を参照しない、ということです。 static がその他の宣言についた場合は無視されます。

class Foo
{
    static int bar() { return 6; }
    int foobar() { return 7; }
}

...

Foo f = new Foo;
Foo.bar();	// 6を返す
Foo.foobar();	// エラー。Fooのインスタンスが無い。
f.bar();	// 6を返す
f.foobar();	// 7を返す

仮想関数はstaticにはできません。

staticデータは、インスタンス毎に一個ずつではなく、 プログラム中に唯一つ保持されます。

Dのstatic属性は、Cのような"ファイルローカル"という別の意味は持ちません。 この用途には、private 属性が使用されます。 例えば:

module foo;
int x = 3;		// x はグローバル
private int y = 4;	// y はモジュールfoo内ローカル

auto属性

auto

auto 属性は、他の属性がなく、 型推論を行いたいときに使用します。

auto i = 6.8;	// i を double 型として宣言

scope属性

scope

scope 属性は、ローカル変数とクラスの宣言に使用できます。 クラス宣言では、scope 属性をつけたクラスは、 scopeクラス となります。 ローカル変数宣言の scope 属性は、RAII (Resource Acquisition is Initialization) を実装するために活用できます。 すなわち、変数がスコープを外れると、オブジェクトのデストラクタが 自動的に呼び出されます。例え例外によってスコープから出るときであっても、 やはりデストラクタが呼ばれます。要するに、scope によって、 何らかの後処理を確実に実行することが保証できます。

二つ以上のscope変数が同じ箇所でスコープを抜ける場合、 デストラクタは、 変数が構築されたのと逆順で実行されます。

scope は、グローバルデータや静的データ、関数の ref/out パラメータには適用できません。scope の配列、関数からの scope 返値も禁止されています。 scope への初期化以外の代入も禁じられています。 Rationale: これらの制限は、 もっともな理由が見つかれば将来的には緩和されるかもしれません。

abstract属性

abstractなクラスは、直接インスタンス化することができません。 他の、abstract でないクラスの基底クラスとしてのみインスタンス化できます。

クラスは、abstract属性付きで宣言された時か、 abstractと宣言された仮想メンバ関数を持っているときに abstractになります。

非仮想関数をabstractと宣言することはできません。

abstract と宣言された関数であっても、関数定義本体を書くことができます。 これは、必ずオーバーライドされる必要があるにせよ、 'クラスの基本共通機能' を提供できるようにするためです。