C++Primer Plus(二)

9161 ワード

C++Primer Plusを完全に読む
システムはC++言語の部分を再学習して、記録は重要ですが無視されやすくて、肝心ですが忘れられやすいです.
 
メモリモデルと名前空間
1、C++標準では、各コンパイラ設計者が適切な方法で名前修飾を実現できるため、異なるコンパイラによって作成されたバイナリモジュールは正しくリンクできない可能性があります.すなわち、2つのコンパイラは、同じ関数に対して異なる修飾名を生成します.名前の違いにより、リンクは、あるコンパイラが生成した関数呼び出しを別のコンパイラが生成した関数定義と一致させることができません.コンパイルモジュールをリンクする場合は、オブジェクトファイルまたはライブラリが同じコンパイラによって生成されていることを確認する必要があります.アクティブなコードの場合、通常、ソースコードを独自のコンパイラで再コンパイルして、すべてのリンクエラーを解消できます.
2、C++は3種類(C++11は4種類)の異なる方を用いてデータを格納する.
自動記憶持続性(関数内の局所変数および関数パラメータ)静的記憶持続性(staticおよび関数外定義変数)動的記憶持続性(new,delete)スレッド記憶持続性(C++11):複数の実行タスクを同時に処理できるマルチコアプロセッサが一般的です.これにより、変数がキーワードthread_localで宣言されている場合、そのライフサイクルは所属するスレッドと同じ長さになります.
3、C++では、キーワードregisterはその意味を失い、変数が自動的であることを示すだけである.
4、デフォルトでは、グローバル変数のリンク性は外部であるが、constグローバル変数のリンク性は内部である.C++から見れば、グローバルconstはstaticを使用しているように見えます.これは、このヘッダファイルを含むコードファイルごとに、定数定義がヘッダファイルに格納される理由です.
5、インライン関数は単一定義規則に拘束されない.これもインライン関数の定義をヘッダファイルに入れることができる理由である.これにより、ヘッダファイルを含む各コードファイルにはインライン関数の定義があるが、C++は同じ関数のすべてのインライン定義を同じにしなければならない.
6、位置決めnew演算子
通常、newはスタック内で要求を満たすのに十分なメモリブロックを見つける責任を負い、new演算子にはnew位置決め演算子と呼ばれ、使用する場所を指定することができ、メモリを割り当てる作業をプログラマーの手に渡す変形があります.
 1 #include<new>
 2 struct chaff
 3 {
 4   char dross[20];
 5   int slag;
 6 };
 7 char buffer1[50];
 8 char buffer2[500];
 9 int main()
10 {
11     char * p1,p2;
12     int * p3,p4;
13     p1 = new chaff;    //    
14     p3 = new int[20];  //    
15     p2 = new (buffer1) chaff;    //   buffer1
16     p4 = new (buffer2) int[20];  //   buffer2
17     ......
18 }

注目すべきは、第1に、位置決めnew演算子の動作原理は、伝達されたアドレスを返し、強制タイプをvoid*に変換するだけである.第二に、位置決め演算子は、どのアドレスが使用されているかを追跡せず、使用されていないかを検索せず、オフセット量(buffer 1+n)指定アドレスを提供することができる.第三に、deleteを使用して前例のメモリを解放することはできない.また、位置決めnew演算子を使用してオブジェクトを作成する場合、コードブロックの終了時に、構造関数を自動的に呼び出すこともありません(呼び出しを表示する必要がある場合もありますが、これは構造関数を明示的に呼び出す数少ない場所です).
7、位置決めnew関数は置換できないが、再ロードでき、少なくとも2つのパラメータを受け入れ、最初は常にstd::size_t,要求のバイト数を指定する.
8、関数のusingコンパイル命令は、名前空間の名前を関数の外で宣言されたものと見なしますが、ファイルの他の関数がこれらの名前を使用できるようにはしません.
9、名前空間と宣言領域が同じ名前を定義していると仮定し、using宣言コマンドを使用して名前空間の名前を宣言領域にインポートすると、この2つの名前が競合し、usingコンパイルコマンドを使用して名前空間の名前を宣言領域にインポートすると、ローカルのバージョンでは名前空間バージョンが非表示になります.
10、ネームスペースに別名を作成できる
1 namespace myspace = std;

11.名前空間の名前を省略して名前空間を作成するとともに、名前空間が属するファイル以外のファイルでは、その名前空間の名前を使用することはできません.これは、内部の静的変数にリンク性を与える代替品です.
12、名前空間の関数が再ロードされた場合、using宣言はすべてのバージョンをインポートします.
 
オブジェクトとクラス
13、クラス宣言の内部に定義された関数は、自動的にインライン関数になります.
14、次の2つのクラスを初期化する構文について、C++標準はコンパイラが2つの方法で2番目の構文を実行することを可能にする.
1 Stock stock1("aaa", 1, 2.1);            // #1
2 Stock stock2 = Stock("bbb", 2, 3.1);    // #2

1つは、最初の構文とまったく同じです.もう1つは、コンストラクション関数を呼び出して一時オブジェクトを作成し、作成するオブジェクトに一時オブジェクトを割り当てます.コンパイラはすぐにコンストラクション関数を呼び出して一時オブジェクトを削除することができますが、しばらく待つこともできます.
15、メンバー関数の定義と宣言の後にconstを加え、メンバー関数がオブジェクトのデータを変更しないことを保証します.constオブジェクトの場合、constによって修飾されていないメンバー関数を呼び出すことはできません.
16.コンストラクション関数を使用してオブジェクト配列の各要素を初期化できます.クラスに複数のコンストラクション関数が含まれている場合、異なる要素に対して異なるコンストラクション関数を使用できます.
1 const int STKS = 10;
2 Stock stocks[STKS] = {
3     Stock("aaa", 12, 13.1),
4     Stock(),
5     Stock("bbb", 12.1, 13),
6 };

呼び出しコンストラクション関数が表示されていない配列要素には、デフォルトのコンストラクション関数が使用されます.
17、最初のUNIXはC++フロントエンドcfrontを使ってC++プログラムをCプログラムに変換することを実現した.
1 void Stock::show() const;
2 void show(const Stock * this);

Stock::修飾子を関数パラメータ(Stockへのポインタ)に変換し、クラスメンバーにポインタでアクセスします.
1 top.show();
2 show(&top);

呼び出しオブジェクトのアドレスをthisポインタに割り当てます.
18.グローバル(ファイル)役割ドメインとローカル(コードブロック)役割ドメインのほか、C++にクラス役割ドメインが追加され、クラスで定義された名前役割ドメインはクラス全体である.
19、クラス内でconstを使用して定数を作成することはできません.クラス宣言はクラスの形式を記述しているだけで、記憶空間を割り当てていません.代わりに列挙を使用します.列挙はシンボル定数を作成しただけで、クラスのデータメンバーにはなりません.整数定数の代わりに列挙を使用できます.もう1つの方法はstaticを使用して定数を修飾し、オブジェクトに格納されずに他の静的変数に格納します.
20、C++11は、クラス役割ドメイン内の列挙名の競合を防止する新しい列挙を提供する.
1 enum class egg {small, medium, large, jumbo};
2 enum class t_shirt {small, medium, large, xlarge};
3 egg choice = egg::large;
4 t_shirt floyd = t_shirt::large;

21、C++11は、役割ドメイン内の列挙のタイプのセキュリティを向上させ、通常の列挙はint変数に値を付与したり、比較式に使用したりする場合に自動的に整数に変換されるが、クラス役割ドメイン内の列挙は暗黙的なタイプ変換を行うことができず、必要に応じて表示されるクラス型変換を行うことができる.
22、C++98の列挙は、実装に応じて、下位整数タイプを使用する.C++11は,役割ドメイン内の列挙に対してこの依存性を解消し,以下の構文を用いることができる.
1 enum class : short pizza {small, medium, large, xlarge};

:shortは下位タイプをshortタイプとして指定し、下位タイプは整数である必要があります.C++11もこの構文をサポートして、通常の列挙下位タイプを指定します.