宣言には次の種類があります。
指定子 基本型 宣言子 初期設定子
宣言子は個々の名前にしか適用されません。よって、
int* a, b;
と記述するのは
int *a; int b;
とするのと同じです。よってこれは
int *a, *b;
とすべきです。
const declaration;
member-function const; // 定数メンバ関数
const (C++) | MSDN
const int a = 1; a = 2; // error C3892: 'a': const である変数へは割り当てることはできません a++; // error C2105: '++' には左辺値が必要です。 int s1 = 10; int p1[s1]; // error C2131: 式は定数に評価されませんでした const int s2 = 10; int p2[s2]; // ok
int p1[] = { 1, 2, 3 }; int* p2 = new int[3]; // 定数を指すポインタ const int* cp = p1; cp[0] = 10; // error C3892: 'cp': const である変数へは割り当てることはできません cp = p2; // ok // ポインタ定数 int* const pc = p1; pc[0] = 10; // ok pc = p2; // error C3892: 'pc': const である変数へは割り当てることはできません // 定数を指すポインタ定数 const int* const cpc = p1; cpc[0] = 10; // error C3892: 'cpc': const である変数へは割り当てることはできません cpc = p2; // error C3892: 'cpc': const である変数へは割り当てることはできません
区分 | 表記 | ポインタのアドレスの変更 | ポインタが指すアドレスにある内容の変更 |
---|---|---|---|
定数を指すポインタ | const type* | ○ | × |
ポインタ定数 | type* const | × | ○ |
定数を指すポインタ定数 | const type* const | × | × |
ハードウェアによって値が変更される可能性があることをコンパイラに示します。これによりコンパイラによる最適化を抑制することができます。volatile (C++) | Microsoft Learn
型のシノニム (同義語) を宣言できます。
typedef type-declaration synonym;typedef 指定子 | MSDN
この場合、すでに定義されている型type-declarationに対して、synonymが新しい名前となります。
typedef unsigned char uchar; uchar a;
typedef char CHAR; typedef CHAR *PSTR;
このように宣言された型でさらに新しい型を宣言する場合には、次のようにカンマ区切りで記述します。
typedef char CHAR, *PSTR;
typedefは通常の識別子と同様のスコープを持ちます。typedef 名の名前空間 | MSDN
ストレージ クラスは、以下を制御する型指定子です。
宣言場所 | 指定子 | 他ファイルからの参照 | 適用範囲 | 生存期間 |
---|---|---|---|---|
関数ブロック内 | static | × | その関数ブロック内のみ | 最初から最後まで |
extern | ○ | |||
関数ブロック外 | static | × | コンパイル単位全体 | |
extern | ○ |
staticなオブジェクトは、プログラムの起動時に割り当てられ、終了時に解放されます。
ローカル | グローバル | 名前空間 | クラス | |
---|---|---|---|---|
変数 | ○ | ○ | ○ | ○ |
関数 | × | ○ | ○ | ○ |
他ファイルから参照できるように、外部リンケージがあるものとして宣言できます。
extern string-literal { declaration-list }
extern string-literal declaration
Microsoft C++はstring-literalとして"C"と"C++"をサポートし、C++プログラムから利用できるように標準的なインクルード ファイルはextern "C"
を使用します。
// Cリンケージを持つようにヘッダを読み込み extern "C" { #include <sample.h> } // Cリンケージを持つ関数の宣言 extern "C" void Func1(); // ... 複数の関数をまとめて宣言 extern "C" { void Func1(); void Func2(); } // ... 関数の定義 extern "C" void Func1() { } // Cリンケージを持つ変数の宣言 extern "C" int x;
Microsoft固有の仕様で、ストレージクラスを拡張する属性を付加できます。
__declspec ( extended-decl-modifier-seq )__declspec | Microsoft Learn
属性 | 作用 |
---|---|
align | 配置を制御する |
allocate | データ項目が割り当てられる、データ セグメントの名前を指定する |
appdomain | マネージド アプリケーションの各アプリケーション ドメインは、特定のグローバル変数または静的メンバー変数の独自のコピーを持つ必要があることを指定する |
code_seg | .objファイル内で関数やクラス メンバー関数のオブジェクト コードが格納される、実行可能なテキスト セグメントを指定する |
deprecated | いくつかの例外を除き、deprecated pragmaと同じ |
dllexport | 関数、データ、オブジェクトを、DLLとの間でエクスポートできる |
dllimport | 関数、データ、オブジェクトを、DLLとの間でインポートできる |
jitintrinsic | 64ビット共通言語ランタイムにとって重要な関数であることを示す |
naked | コンパイラにプロローグおよびエピローグ コードのないコードを生成するように指示する |
noalias | ポインタ パラメータによって示されるdirectlyが指すメモリ ポインタしか、変更しないことを意味する |
noinline | 特定のメンバー関数 (クラス内の関数) を、インラインにしないことをコンパイラに伝える |
noreturn | コンパイラに、関数が戻らないことを伝える |
nothrow | 関数とそれが呼び出す関数が、例外をスローしないことをコンパイラに伝える |
novtable | クラスのコンストラクターおよびデストラクター内のvfptrを初期化するコードをコンパイラが生成することを阻止する |
process | マネージド アプリケーション プロセスが、プロセス内のすべてのアプリケーション ドメイン間で共有される特定のグローバル変数、静的メンバー変数、静的ローカル変数の、コピーを1つ持つことを指定する |
restrict | 関数が他のポインターで別名を与えられないオブジェクトを返すことをコンパイラに伝える |
safebuffers | 関数のバッファー オーバーラン セキュリティ チェックを挿入しないようにコンパイラに伝える |
selectany | 宣言されたグローバル データ項目がpick-any COMDAT (パッケージ化された関数) であることをコンパイラに伝える |
thread | スレッド ローカル変数を宣言する |
uuid | コンパイラはクラスや構造体の宣言や定義に、GUIDを添付する |
namespace MyNamespace { void Func1(); void Func2(); }
void MyNamespace::Func1() {} void MyNamespace::Func2() {}
void main() { MyNamespace::Fun1(); }
void main() { using MyNamespace::Fun1; // 関数名まで指定 using MyNamespace::Fun2; Fun1(); // 名前空間は不要 Fun2(); }
namespace MyNamespace1 { void Func1(); void Func2(); using namespace MyNamespace2; }using directives - Namespaces (C++) | Microsoft Learn
usingディレクティブをヘッダー ファイルに記述しないようにします。記述すると、それをインクルードするすべてのファイルに適用され、名前の隠蔽や競合を起こす恐れがあります。
namespace MyNamespace { class MyClass {}; } namespace A = MyNamespace; void Func(A::MyClass myClass){ }名前空間エイリアス - 名前空間 (C++) | MSDN
グローバル スコープで宣言されている関数には、次のようにしてもアクセスできます。
::Func();