C++でソースコードに関数の説明などを書くときはコメントを使います。しかしコメントは当然のことながらコンパイルした結果には何の情報も残しません。属性(attribute)とは、コメントのようにクラスやメソッドに付加情報を与えるための仕組みです。そして属性はコンパイルした結果のEXE やDLLのメタデータの中に書き込まれます。
属性は、コメントとは違い書き方が決まっています。そしてあらかじめ使い方が決まっている属性もあれば、自分が利用するためのカスタム属性を作成することもできます。またコメントと違い属性はどこに書いてもいいというものではなく、クラスの属性、関数の属性など、その適用先を指定して利用します。
古くなったメソッドにObsolete属性をつけて、それを利用する人に警告する例を以下に示します。
using namespace System; ref class C { public: [Obsolete("use newfunc()")] void oldfunc() {} void newfunc() {} }; int main() { C^ c = gcnew C; c->newfunc(); c->oldfunc(); // warning return 0; }
上記のように属性は[ ]で書きます。属性の指定先はその下にあるものになります。この場合はoldfunc()です。そしてこのObsoleteは、実は ObsoleteAttributeというクラスなのです。そして属性クラスはAttributeクラスから派生しています。
“use newfunc()“はObsoleteAttributeクラスのコンストラクタに渡している引数と言う意味になります。マニュアルを読むとこのクラスのコンストラクタは3種類あり、以下のように使えば、warningではなくエラーとして扱えることがわかります。
[Obsolete("use newfunc()", true)]
なお上記の[Obsolete(”…”)]は、[ObsoleteAttribute(“…”)]と書くこともできます。
アセンブリそのものに属性をつけることもできます。以下のように書きます。
[assembly:AssemblyTitleAttribute("MyApp")];
アップウイザードで[空のプロジェクト]以外でプロジェクトを作成した場合、“AssemblyInfo.cpp” にアセンブリの属性がまとめて登録されています。上記の属性はその名のとおりアセンブリに名前 (Title)をつける属性です。
上記の記述は以下のようにAttributeを省略して書くこともできます。
[assembly:AssemblyTitle("MyApp")]
属性にはその属性の適用先が指定されている場合があります。例えば上記のAssemblyTitleAttribute クラスの仕様を見ると以下のように定義されています。
[ComVisibleAttribute(true)] [AttributeUsageAttribute(AttributeTargets::Assembly, Inherited=false)] public ref class AssemblyTitleAttribute sealed : public Attribute
上記の
[AttributeUsageAttribute(AttributeTargets::Assembly, Inherited=false)]
によって、AssemblyTitleAttributeはアセンブリに対してしか適用できないことになります。