C++ のクラスは、キーワード、または(最初の 2 つはまとめて非共用体クラスと呼ばれます)のいずれかで宣言されたユーザー定義の型またはデータ構造であり、そのメンバーとしてデータと関数 (メンバー変数およびメンバー関数とも呼ばれます) を持ち、そのアクセスは 3 つのアクセス指定子private、protected、またはpublicによって制御されます。 デフォルトでは、キーワードで宣言された C++ クラスのメンバーへのアクセスはprivateです。プライベート メンバーはクラスの外部からアクセスできません。クラスのメンバー関数を通じてのみアクセスできます。パブリック メンバーはクラスへのインターフェイスを形成し、クラスの外部からアクセスできます。
classstructunion class
クラス データ型のインスタンスはオブジェクトと呼ばれ、プログラマーによって定義された メンバー変数、定数、メンバー関数、オーバーロードされた演算子を含めることができます。
C++ におけるstructとの違いclass
C++ では、キーワードで定義されたクラスは、デフォルトでプライベートメンバーと基本クラスをclass持ちます。構造体は、キーワードで定義されたクラスです。 [1]メンバーと基本クラスはデフォルトでパブリックです。実際には、構造体は通常、関数のないデータ用に予約されています。クラス/構造体から構造体を派生する場合、基本クラス/構造体のデフォルトのアクセス指定子は public です。また、クラスを派生する場合、デフォルトのアクセス指定子は private です。
struct
集約クラス
集約クラスとは、ユーザーが宣言したコンストラクタ、プライベートまたは保護された非静的データメンバー、基本クラス、仮想関数を持たないクラスです。[2]このようなクラスは、中括弧で囲まれたコンマ区切りの初期化句のリストで初期化できます。[3]次のコードは、C と C++ の両方で同じセマンティクスを持ちます。
構造体C { int a ; double b ; };
構造体D { int a ; double b ; C c ; };
// 初期化リストを使用して C 型のオブジェクトを初期化します。C
c = { 1 , 2.0 } ;
// Dには C 型のサブ集約があります。このような場合、初期化句はネストできます。D d = { 10 , 20.0 , { 1 , 2.0 }};
POD構造
POD構造体(Plain Old Data Structure)は、非POD構造体、非POD共用体(またはそのような型の配列)、参照型の非静的データメンバーを持たず、ユーザー定義の代入演算子やユーザー定義のデストラクタを持たない非共用体集約クラスです。[1] POD構造体は、CのC++版と言えますstruct。ほとんどの場合、POD構造体は、Cで宣言された対応する構造体と同じメモリレイアウトを持ちます。[4]このため、POD構造体は口語的に「Cスタイルの構造体」と呼ばれることもあります。[5]
C の構造体と C++ の POD 構造体の間で共有されるプロパティ
- データメンバーは、アクセス指定子によって区切られている場合を除き、後続のメンバーがオブジェクト内でより高いアドレスを持つように割り当てられます。[6]
- 2つのPOD構造体型は、非静的データメンバーの数が同じで、対応する非静的データメンバー(順番に)がレイアウト互換型である場合にレイアウト互換です。[7]
- POD構造体には名前のないパディングが含まれることがある。[8]
- 再解釈キャストを使用して適切に変換されたPOD構造体オブジェクトへのポインタは、その最初のメンバーを指し、その逆も同様です。これは、POD構造体の先頭にパディングがないことを意味します。[8]
- POD構造体はoffsetofマクロと一緒に使用できます。[9]
宣言と使用
C++ クラスには独自のメンバーがあります。これらのメンバーには、変数 (他の構造体やクラスを含む)、メンバー関数と呼ばれる関数 (特定の識別子またはオーバーロードされた演算子)、コンストラクタ、およびデストラクタが含まれます。メンバーは、それぞれ および アクセス指定子を使用して、パブリックまたはプライベートにアクセス可能であると宣言されますpublic:。private:指定子の後に検出されたメンバーは、別の指定子が検出されるまで、関連付けられたアクセス権を持ちます。指定子を利用できるクラス間の継承もありますprotected:。
グローバルクラスとローカルクラス
すべての関数の外部で定義されたクラスは、そのオブジェクトがプログラム内のどこからでも作成できるため、グローバル クラスです。関数本体内で定義されたクラスは、そのクラスのオブジェクトが関数スコープに対してローカルであるため、ローカル クラスです。
基本的な宣言とメンバー変数
非共用体クラスは、classorstruct キーワードを使用して宣言されます。メンバーの宣言はこの宣言内に配置されます。
上記の定義は機能的に同等です。どちらのコードでも、 型のオブジェクトはPerson2 つのパブリック データ メンバーと を持つものとしてname定義されますage。閉じ括弧の後の
セミコロンは必須です。
これらの宣言のいずれか (両方ではない) の後に、Person次のように使用して、データ型の新しく定義された変数を作成できますPerson。
#include <iostream> #include <文字列>
構造体Person { std :: string名前; int年齢; };
int main () { Person a ; Person b ; a . name = "Calvin" ; b . name = "Hobbes" ; a . age = 30 ; b . age = 20 ; std :: cout << a . name << ": " << a . age << std :: endl ; std :: cout << b . name << ": " << b . age << std :: endl ; }
上記のコードを実行すると、出力は次のようになります。
カルビン:30 ホッブズ:20
メンバー関数
C++ クラスの重要な機能はメンバー関数です。各データ型には、そのデータ型のすべてのメンバー (パブリックおよびプライベート) にアクセスできる独自の組み込み関数 (メンバー関数と呼ばれる) があります。これらの非静的メンバー関数の本体では、キーワードをthis使用して、関数が呼び出されるオブジェクトを参照できます。これは通常、オブジェクトのアドレスを関数の暗黙的な最初の引数として渡すことによって実装されます。[10]上記のPerson型をもう一度例として挙げます。
#include <iostream>
クラスPerson { public : void Print () const ;
private :
std :: string name_ ; int age_ = 5 ; //C++ 11 };
void Person::Print () const { std :: cout << name_ << ':' << age_ << '\n' ; // "name_" と "age_" はメンバー変数です。"this" キーワードは、メンバーが呼び出されたオブジェクトのアドレスを値とする式です。関数がconst として宣言されているため、その型は "const Person*" です。 }
上記の例では、Print関数はクラスの本体で宣言され、クラス名の後に を付けて修飾することで定義されます::。 と は両方name_ともage_プライベート (クラスのデフォルト) であり、 はPrintクラス外部から使用する場合に必要となるパブリックとして宣言されています。
メンバー関数を使用するとPrint、印刷は次のように簡略化されます。
a .印刷();
b .印刷();
上記は送信者aとb呼ばれ、関数の実行時にそれぞれ独自のメンバー変数を参照しますPrint()。
クラスまたは構造体の宣言 (インターフェースと呼ばれる) と定義 (実装と呼ばれる) を別々のユニットに分けるのが一般的です。ユーザーに必要なインターフェースはヘッダーに保持され、実装はソース形式またはコンパイルされた形式で別々に保持されます。
継承
メモリ内の非 POD クラスのレイアウトは、C++ 標準では指定されていません。たとえば、多くの一般的な C++ コンパイラは、親クラス フィールドと子クラス フィールドを連結することによって単一継承を実装していますが、これは標準では必須ではありません。このレイアウトの選択により、親クラス型へのポインターを介して派生クラスを参照することが簡単な操作になります。
例えば、
構造体P { int x ; };
構造体C : P { int y ; };
を指す
Pのインスタンスは、メモリ内で次のようになります。P* p
┏━━━━┓ ┃P::x┃ ┗━━━━┛ ↑ p
を指す
Cのインスタンスは次のようになります。P* p
┏━━━━┳━━━━┓ ┃P::x┃C::y┃ ┗━━━━┻━━━━┛ ↑ p
したがって、オブジェクトのフィールドを操作するコードは、オブジェクトのフィールドの定義について何も考慮することなく、オブジェクト内のフィールドをP操作できます。適切に記述された C++ プログラムでは、継承されたフィールドのレイアウトについて何も想定する必要はありません。static_castまたはdynamic_cast型変換演算子を使用すると、ポインターが 1 つの型から別の型に適切に変換されることが保証されます。
PCC
多重継承はそれほど単純ではありません。クラスがと をD継承する場合、両方の親のフィールドを何らかの順序で格納する必要がありますが、派生クラスの先頭に配置できるのは (多くても) 親クラスの 1 つだけです。コンパイラが 型からまたはのいずれかにポインターを変換する必要がある場合は、コンパイラは派生クラスのアドレスから基本クラス フィールドのアドレスへの自動変換を提供します (通常、これは単純なオフセット計算です)。
PCDPC
多重継承の詳細については、仮想継承を参照してください。
キーワードfinal は、クラスをサブクラス化できる方法を制限します。[11]クラスのサブクラスは、final親クラスによって としてマークされたメソッドをオーバーライドできません。[12] [13] finalクラスは継承できません。[13]これにより、仮想化解除、つまりメソッド検索のためのvtableの使用が削除され、 finalクラスでのメソッド呼び出しのインライン化が可能になります。 [14] [15]
finalはC++では予約語ではなく、既存のコードベースでの識別子「final」の使用と競合しないようにコンテキストキーワードとして定義されています。[16] [17]
オーバーロードされた演算子
C++ では、などの演算子は+ - * /、プログラマのニーズに合わせてオーバーロードできます。これらの演算子は、オーバーロード可能な演算子と呼ばれます。
慣例により、オーバーロードされた演算子は組み込みデータ型 ( int、floatなど) の場合とほぼ同じように動作しますが、これは必須ではありません。 と呼ばれる構造体を宣言し、Integerその変数に実際に整数を格納することができますが、Integer * Integerを呼び出すと、整数の積ではなく和が返される場合があります。
構造体Integer { Integer () =デフォルト; Integer ( int j ) : i { j } {}
整数演算子* ( const Integer & k ) const { return Integer ( i + k . i ); }
整数i = 0 ; };
上記のコードでは、コンストラクタを使用して戻り値を「構築」しています。より明確な表現のために (ただし、コンパイラがステートメントを上記の同等のステートメントに最適化できない場合は、プログラムの効率が低下する可能性があります)、上記のコードは次のように書き直すことができます。
整数演算子* ( const Integer & k ) const { Integer m ; m . i = i + k . i ; return m ; }
プログラマーは、宣言に演算子のプロトタイプを配置しstruct、グローバル スコープで演算子の機能を定義することもできます。
構造体Integer { Integer () =デフォルト; Integer ( int j ) : i { j } {}
整数演算子* ( const Integer & k ) const ;
int i = 0 ; };整数Integer :: operator * ( const Integer & k ) const { return Integer ( i * k . i ); }
i上記は送信者自身のメンバー変数を表し、 はk.i引数変数のメンバー変数を表しますk。
キーワードconstは上記のコードに 2 回出現します。最初の出現である argument はconst integer& k、関数によって引数変数が変更されないことを示します。宣言の最後の 2 番目の出現は、関数の実行によって送信元が変更されないことを
コンパイラーに保証します。
ではconst integer& k、アンパサンド(&) は「参照渡し」を意味します。関数が呼び出されると、変数の値ではなく、変数への参照が関数に渡されます。
演算子のアリティ、結合性、優先順位は変更できない ことに注意してください。
バイナリオーバーロード可能な演算子
バイナリ演算子 (2 つの引数を持つ演算子) は、1 つの引数を呼び出す「識別子」演算子 (何か)を持つ関数を宣言することによってオーバーロードされます。演算子の左側の変数は送信元であり、右側の変数は引数です。
Integer i = 1 ; /*最初の 引数のみを指定し てコンストラクターを呼び出すのと同じように、構造体変数を初期化できます。 */ Integer j = 3 ; /* 変数名は、構造体のメンバー変数の名前とは無関係です 。 */ Integer k = i * j ; std :: cout << k . i << '\n' ;
「3」が印刷されます。
以下はバイナリオーバーロード可能な演算子のリストです。
同じ構造型の 2 つの変数間の '=' (代入) 演算子は、デフォルトでオーバーロードされ、変数の内容全体が一方から他方にコピーされます。必要に応じて、他の演算子で上書きできます。
演算子は 1 つずつオーバーロードする必要があります。つまり、オーバーロードは相互に関連付けられません。たとえば、<は必ずしも の反対であるとは限りません>。
単項オーバーロード可能な演算子
上で指定したように、一部の演算子は左側の送信者と右側の引数の 2 つの項を取りますが、一部の演算子は引数が 1 つ (送信者) のみで、これらは「単項」と呼ばれます。例としては、負の記号 (左側に何も置かない場合) や「論理NOT」(感嘆符, !) などがあります。
単項演算子の送信者は、演算子の左側または右側に配置できます。以下は、単項オーバーロード可能な演算子のリストです。
送信者が右側にある単項演算子のオーバーロードの構文は次のとおりです。
return_type operator@ ()
送信者が左側にある場合、宣言は次のようになります。
return_type operator@ (int)
@上記はオーバーロードされる演算子を表します。return_type戻り値のデータ型(int、、bool構造体など)
に置き換えます。
パラメータintは本質的には、送信者が演算子の左側にあることを示す規則以外の何物でもありません。
const該当する場合は、宣言の最後に引数を追加できます。
括弧のオーバーロード
C++ クラスでは、角括弧[]と丸括弧を()オーバーロードできます。角括弧には 1 つの引数のみを含める必要がありますが、丸括弧には任意の数の引数を含めることができ、引数を含めなくてもかまいません。
次の宣言は角括弧をオーバーロードします。
return_type operator[] (argument)
括弧内の内容は、そのargument部分で指定します。
丸括弧も同様の方法でオーバーロードされます。
return_type operator() (arg1, arg2, ...)
演算子呼び出し内の括弧の内容は、2 番目の括弧で指定されます。
上記で指定した演算子に加えて、矢印演算子 ( ->)、星印付き矢印 ( ->*)、newキーワード、およびdeleteキーワードもオーバーロードできます。これらのメモリまたはポインタ関連の演算子は、オーバーロード後にメモリ割り当て関数を処理する必要があります。代入演算子 ( =) と同様に、特に宣言が行われていない場合は、これらもデフォルトでオーバーロードされます。
コンストラクター
プログラマーは、変数の宣言時にデフォルト値または特定の値を設定することを望む場合があります。これは、コンストラクターを宣言することで実現できます。
Person :: Person (文字列名, int年齢) { name_ =名前; age_ =年齢; }
メンバー変数は、以下の例のようにコロンを使用して初期化リストで初期化できます。これは、代入演算子を使用するのではなく、コンストラクターを使用して初期化する点で上記とは異なります。これは、クラス型の場合は直接構築するだけでよいため、より効率的です。一方、代入の場合は、最初にデフォルト コンストラクターを使用して初期化してから、別の値を割り当てる必要があります。また、一部の型 (参照型やconst型など) は割り当てることができないため、初期化リストで初期化する必要があります。
Person ( std :: string name , int age ) : name_ (名前), age_ (年齢) {}
中括弧は空の場合でも省略できないことに注意してください。
デフォルト値を初期化するために、最後の引数にデフォルト値を指定できます。
Person ( std :: string name = "" 、int age = 0 ) : name_ (名前)、age_ (年齢) {}
上記の例でコンストラクターに引数が指定されていない場合は、次のコンストラクターを引数なしで呼び出すことと同じです (デフォルト コンストラクター)。
人() :名前_ ( "" )、年齢_ ( 0 ) {}
コンストラクタの宣言は、データ型と同じ名前を持つ関数のように見えます。実際、コンストラクタの呼び出しは関数呼び出しの形式を取ることができます。その場合、初期化されたPerson型変数は戻り値と考えることができます。
int main () { Person r = Person ( "Wales" , 40 ); r . Print (); }
上記の例と同じことを行う別の構文は
int main () { Person r ( "ウェールズ" , 40 ); r . Print (); }
変数に関連するかどうかに関係なく、特定のプログラム アクションをコンストラクターの一部として追加できます。
Person () { std :: cout << "Hello!" << std :: endl ; }
上記のコンストラクターでは、デフォルトのPersonコンストラクターが呼び出されると、「Hello!」が出力されます。
デフォルトコンストラクタ
クラスにコンストラクターが定義されていない場合は、デフォルト コンストラクターが呼び出されます。
struct A { int b ; }; // 括弧を使用してオブジェクトを作成します。A * a = new A (); // デフォルト コンストラクターを呼び出し、b は '0' で初期化されます。// 括弧を使用せずにオブジェクトを作成します。A * a = new A ; // メモリを割り当ててからデフォルト コンストラクターを呼び出します。b の値は '0' になります。// new を使用せずにオブジェクトを作成します。A a ; // スタック上に a 用のスペースを予約します。b は不明なガベージ値になります。
ただし、クラスにユーザー定義のコンストラクターが定義されている場合、上記の両方の宣言でこのユーザー定義のコンストラクターが呼び出され、定義されたコードが実行されますが、変数 b にはデフォルト値は割り当てられません。
デストラクタ
デストラクタはコンストラクタの逆です。クラスのインスタンスが破棄されるときに呼び出されます。たとえば、ブロック (中括弧のセット "{}") で作成されたクラスのオブジェクトが閉じ括弧の後で削除されると、デストラクタが自動的に呼び出されます。変数を格納するメモリ位置が空になると、デストラクタが呼び出されます。デストラクタは、そのクラスのインスタンスが破棄されるときに、ヒープに割り当てられたメモリや開かれたファイルなどのリソースを解放するために使用できます。
デストラクタを宣言する構文は、コンストラクタの構文と似ています。戻り値はなく、関数名はクラス名の前にチルダ (~) が付いたものと同じです。
~ Person () { std :: cout << "年齢が " << name_ << "を削除しています" << age_ << std :: endl ; }
コンストラクタとデストラクタの類似点
- どちらも、宣言されているクラスと同じ名前を持ちます。
- ユーザーが宣言していない場合、両方ともデフォルトでクラスで使用できますが、オブジェクトが宣言または削除されたときにのみ、クラスのオブジェクトからメモリを割り当てたり割り当て解除したりすることができます。
- 派生クラスの場合: 基本クラスのコンストラクターの実行時には、派生クラスのコンストラクターはまだ呼び出されていません。基本クラスのデストラクターの実行時には、派生クラスのデストラクターが既に呼び出されています。どちらの場合も、派生クラスのメンバー変数は無効な状態です。
クラステンプレート
C++ では、クラス宣言はクラス テンプレートから生成できます。このようなクラス テンプレートはクラスのファミリを表します。実際のクラス宣言は、 1 つ以上のテンプレート引数を使用してテンプレートをインスタンス化することによって取得されます。特定の引数セットを使用してインスタンス化されたテンプレートは、テンプレートの特殊化と呼ばれます。
プロパティ
C++ の構文は、クラスのあらゆる側面を基本データ型のそれと同じにしようとします。したがって、オーバーロードされた演算子を使用すると、クラスを整数や浮動小数点数のように操作でき、クラスの配列は角括弧構文 ( some_structure variable_name[size]) を使用して宣言でき、クラスへのポインターは組み込みデータ型へのポインターと同じ方法で逆参照できます。
メモリ消費量
構造体のメモリ消費量は、構成変数のメモリ サイズの合計以上になります。TwoNums以下の構造体を例に挙げます。
構造体TwoNums { int a ; int b ; };
この構造体は 2 つの整数で構成されます。現在の多くの C++ コンパイラでは、整数は デフォルトで32 ビット整数であるため、各メンバー変数は 4 バイトのメモリを消費します。したがって、構造体全体では、次のように少なくとも (または正確に) 8 バイトのメモリを消費します。
+----+----+ | ア | ロ | +----+----+
ただし、コンパイラは、特定のコンピュータアーキテクチャで適切なデータアラインメントを確保するために、変数間または構造体の末尾にパディングを追加することがあります。多くの場合、変数は32ビットアラインメントになるようにパディングされます。たとえば、構造体
構造体BytesAndSuch { char c ; char C ; char D ; short int s ; int i ; double d ; };
こんな感じ
+-+-+-+--+--+----+--------+ |c|C|D|X|s |XX| i | d | +-+-+-+--+--+----+--------+
メモリ内で、X は4 バイトのアライメントに基づいてパディングされたバイトを表します。
構造体はポインターと配列を使用してメンバー変数を宣言および初期化するため、構造体のメモリ消費量は必ずしも一定ではありません。メモリ サイズが一定でない別の例として、テンプレート構造体があります。
ビットフィールド
ビット フィールドは、整数型よりも少ないストレージを占有できるクラス メンバーを定義するために使用されます。このフィールドは、整数型 (int、char、short、long など) と列挙型 (std::byte など) にのみ適用され、float または double には適用されません。
struct A { unsigned a : 2 ; // 可能な値 0..3、int の最初の 2 ビットを占有unsigned b : 3 ; // 可能な値 0..7、int の次の 3 ビットを占有unsigned : 0 ; // 次の整数型の末尾に移動するunsigned c : 2 ; unsigned : 4 ; // c と d の間に 4 ビットを埋め込むunsigned d : 1 ; unsigned e : 3 ; };
- メモリ構造
4バイト整数 4バイト整数 [1][2][3][4][5][6][7][8] [1] [2] [3] [4] [a][a][b][b][b][ ][ ][ ] [ ][ ... [5] [6] [7] [8] [c][c][ ][ ][ ][ ][ ][d][e] [e][e][ ][ ][ ][ ][ ][ ][ ][ ] [ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] [ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
共用体にはビットフィールド メンバーも許可されます。
union A { unsigned a : 2 ; unsigned b : 3 ; unsigned : 0 ; // 何もしませんunsigned c : 2 ; unsigned : 4 ; // この場合は何もしません。ビットフィールドの幅が十分に大きい場合は、union のサイズがそれに合わせて変更されますunsigned d : 1 ; unsigned e : 3 ; };
通り過ぎる参照
多くのプログラマーは、構造体を含む関数の引数を宣言するためにアンパサンド (&) を使用することを好みます。これは、逆参照アンパサンドを使用すると、関数に渡す必要があるのは 1 ワード (通常、32 ビット マシンでは 4 バイト、64 ビット マシンでは 8 バイト)、つまり変数のメモリ位置だけだからです。そうでない場合、値渡しを使用すると、関数が呼び出されるたびに引数をコピーする必要があり、大きな構造体ではコストがかかります。
参照渡しでは、関数によって変更される元の構造が公開されるため、意図していない場合にconst関数がパラメータを変更しないことを保証するために、キーワードを使用する必要があります ( const-correctnessを参照)。
のこれキーワード
クラスが自分自身を参照できるようにするために、C++ではthisすべてのメンバー関数にキーワードを実装しています。thisキーワードは現在のオブジェクトへのポインタとして機能します。[18]その型は現在のオブジェクトへのポインタ型です。
このthisキーワードは、クラス自体を戻り値として持つメンバー関数にとって特に重要です。
Complex &演算子+= ( const Complex & c ) { real_part_ += c . real_part_ ; imag_part_ += c . imag_part_ ; return * this ; }
前述のとおり、thisはポインターなので、返される参照に変換するには
アスタリスク(*) を使用する必要があります。
参照
参考文献
- ^ ab ISO / IEC (2003). ISO/IEC 14882:2003(E): プログラミング言語 - C++ §9 クラス [クラス]パラグラフ 4
- ^ ISO / IEC (2003). ISO/IEC 14882:2003(E): プログラミング言語 - C++ §8.5.1 集約 [dcl.init.aggr]パラグラフ 1
- ^ ISO / IEC (2003). ISO/IEC 14882:2003(E): プログラミング言語 - C++ §8.5.1 集約 [dcl.init.aggr]パラグラフ 2
- ^ 「よく耳にする C++ の「POD」とは何ですか?」Comeau Computing。2009 年 1 月 19 日時点のオリジナルよりアーカイブ。2009年 1 月 20 日閲覧。
- ^ Henricson, Mats; Nyquist, Erik (1997). Industrial Strength C++ . Prentice Hall. ISBN 0-13-120965-5。
- ^ ISO / IEC (2003). ISO/IEC 14882:2003(E): プログラミング言語 - C++ §9.2 クラスメンバー [class.mem]パラグラフ 12
- ^ ISO / IEC (2003). ISO/IEC 14882:2003(E): プログラミング言語 - C++ §9.2 クラスメンバー [class.mem]パラグラフ 14
- ^ ab ISO / IEC (2003). ISO/IEC 14882:2003(E): プログラミング言語 - C++ §9.2 クラスメンバー [class.mem]パラグラフ 17
- ^ ISO / IEC (2003). ISO/IEC 14882:2003(E): プログラミング言語 - C++ §18.1 型 [lib.support.types]パラグラフ 5
- ^ "thiscall (C++)" . 2009年1月26日閲覧。
- ^ ISO 国際規格 ISO/IEC 14882:2020(E) – プログラミング言語 C++。
- ^ Browning, J. Burton; Sutherland, Bruce (2020)、Browning, J. Burton; Sutherland, Bruce (編)、「継承」、C++20 Recipes: A Problem-Solution Approach、カリフォルニア州バークレー: Apress、pp. 205–207、doi :10.1007/978-1-4842-5713-5_6、ISBN 978-1-4842-5713-5、2024-04-24取得
- ^ ab Lakos, John; Romeo, Vittorio; Khlebnikov, Rostislav; Meredith, Alisdair (2021-12-16). 安全に最新の C++ を取り入れる。Addison-Wesley Professional。ISBN 978-0-13-738051-0。
- ^ 「16BPP.net: ブログ / C++ の「final」キーワードのパフォーマンスへの影響」。16bpp.net。2024年 4 月 23 日閲覧。
- ^ Brand, Sy (2020-03-02). 「final クラスのパフォーマンス上の利点」。C ++ チーム ブログ。2024年 4 月 23 日閲覧。
- ^ TylerMSFT (2021-08-03). 「final 指定子」. learn.microsoft.com . 2024-04-23に取得。
- ^ Stroustrup, Bjarne (2013-07-10). C++ プログラミング言語. Addison-Wesley. ISBN 978-0-13-352285-3。
- ^ "this". C++ リファレンス.
一般的な参考文献:
- Cplusplus.com チュートリアル レッスン 5.2 2009-04-03 にWayback Machineにアーカイブされ、2006 年 1 月にアクセスされました
- Cplusplus.com チュートリアル レッスン 2.5 2009-03-30 にWayback Machineにアーカイブされ、2006 年 2 月にアクセスされました
