ポインタ・リテラル
変数の定義
- 定義形式:型指定子+1つ以上の変数名のリスト。例えば、int sum = 0, value, units_sold = 0;
- 初期化:オブジェクトの作成時に特定の値を取得します。
- 初期化は代入ではありません。
- 初期化 = 変数の作成 + 初期値の割り当て
- 代入 = オブジェクトの現在の値を消去し、新しい値に置き換えます。
- リスト初期化:中括弧 {} を使用します(例:int units_sold{0});
- デフォルトの初期化:定義時に初期値が指定されていない場合、デフォルトで初期化されます。
- 組み込み型の変数はすべて初期化することをお勧めします。
変数の宣言と定義
- 定義せずに宣言する:変数名の前にexternというキーワードを付けます。しかし、初期値が含まれていれば、extern double pi = 3.14 のように定義されます;
- 変数は一度しか定義できませんが、複数回宣言することができます。
複合型
参照 右値参照は、第13章では主に組み込みクラスで使用されます。
- 参照:参照はオブジェクトの別名で、参照型は別の型を参照します。例えば、int &refVal = val とします。
- 参照は初期化する必要があります。
- 参照とその初期値はコピーされるのではなく、結合されます。
ポインタ
- ポインタへの参照:参照はそれ自体オブジェクトではないので、参照へのポインタを定義することはできません。しかし、ポインターはオブジェクトなので、ポインターへの参照が存在します。
int i = 42;
int *p;
int *&r = p; //rはポインタpへの参照である。
r = &i; //つまり、pがi
*r = 0; //すなわち、iの値は0に変更される。
const
初期化と const
- constオブジェクトは初期化されなければならず、変更することはできません。
const int i = get_size() // 可能:実行時の初期化
const int j = 42; //コンパイル時に初期化される。
const int k; //
- デフォルトでは、const オブジェクトはファイル内でのみ有効です。
コンパイル時に初期化された方法で const オブジェクトを定義する場合、 const int bufSize = 512; コンパイラはコンパイル時にこの変数を対応する値に置き換えます。
- 複数のファイル間で const オブジェクトを共有するには、変数定義に extern キーワードを追加します。
//file_1.cc
extern const int bufSize = f);
//file_1.h
extern const int bufSize; //同じbufSizeである。
const
const int ci = 1024;
const int &r1 = ci;
r1 = 42; //エラーr1は定数への参照である。
int &r2 = ci; //エラー 定数でない参照を定数オブジェクトにポイントさせようとした
int i = 42;
const int &r1 = i;//ヘッダー・プロテクターは、const int& プレーンなintオブジェクトにバインドする
cosnt int &r2 = 42;
const int &r3 = r1*2;
int &r4 = r1*2;//エラーr4は通常の非定数参照である。
- 定数参照は、参照されるオブジェクトがそれ自体定数であるかどうかについては修飾されません。
int i = 42;
int &r1 = i;
const int &r2 = i;
r1 = 0; //
r2 = 0; //エラー、r2は定数参照である。
ポインタとconst(定数オブジェクトのアドレスを保持。)
const double pi = 3.14;
double *ptr = π //
const double *cptr = π
*cptr = 42;//エラー、不変
- 定数参照が定数でないものを指すのと同じように、定数へのポインタも定数でないものを指すことができます。
const
- 定数ポインタは初期化する必要があり、初期化完了後も値は変更されません。
int errNumb = 0;
int *const curErr = &errNumb; //は常にerrNumbを指す。
const double pi = 3.14;
const double *const pip = π
トップレベル const とボトムレベル const
- コピーの際には、同じconst修飾子が厳密に必要です。int* は const int* に変換できます。 const int& は通常の int にバインドできます。
constexprおよび定数式
- 定数式とは、値が変化せず、コンパイラがその結果を利用できる式のことです。
const int max_files = 20; //max_filesは定数表現である。
const int limit = max_files + 1; //limitは定数表現である。
int staff_size = 27; //staff_size定数式ではない
const int sz = get_size(); //sz定数式ではない
- constexpr変数:コンパイラが変数の値が定数式であることを確認するために、変数をconstexprとして宣言できるようにします。constexprとして宣言された変数は定数でなければならず、定数式で初期化されなければなりません:
constexpr int mf = 20; //20は定数表現である。
constexpr int limit = mf + 1; //mf+1は定数表現である。
constexpr int sz = size() //sizeがconstexpr関数の場合は正しい!
- 通常の関数を constexpr の初期値として使用することはできません。変数を定数式として識別する場合は、constexpr 型として宣言してください。
const int *p = nullptr;
constexpr int *q = nullptr;//constexpr定義したオブジェクトをトップレベルのconst
処理タイプ
型エイリアス
typedef double wages;
typedef wages base,*p; //pこれはダブル*の同義語は
using SI = Sales_item;
SI item; //セールス_item
ポインタ、定数、および型のエイリアス
typedef char *pstring;
const pstring cstr = 0;
const pstring *ps;
auto型指定子
auto item = val1 + val2;
auto i = 0,*p = &i;
auto sz = 0,pi = 3.14; //エラー タイプの不一致
- 最上位の const は無視され、最下位の const は保持されます。
const int ci = i,&cr = ci;
auto b = ci;
auto c = cr;
auto d = &i;
auto e = &ci;//定数オブジェクトのアドレスを取ることは、基礎となるconst
- 推論される自動型をトップレベルの const にしたい場合は、明示的にそう指定する必要があります:
const auto f = ci;
- 参照のタイプを auto に設定することもできます。
auto &g = ci;
auto &h = 42;//エラー リテラル値を定数でない参照にバインドできない
const auto &j = 42;//リテラル値は定数参照にバインドできる。
decltype(f()) sum = x; //sumの型は関数fの戻り値の型である。
const int ci = 0,&cj = ci;
decltype(ci) x = 0; //x変数の型は、const int
decltype(cj) y = x; //y変数の型は、const int&,y変数xへのバインド
decltype(cj) z; //エラー z は参照であり、初期化する必要がある。
int i = 42,*p = &i,&r = i;
decltype(r+0) b; //追加された結果は、int
decltype(*p) c; //cこれはint&,初期化する必要がある。
decltype((i)) d; //dこれはint&,初期化する必要がある。
decltype(i) e; //正しいeは未初期化のintである。
独自のヘッダーファイルを作成
- decltype型インジケーター
- プリプロセッサ: 複数のインクルードがあってもヘッダーファイルが安全に動作するようにします。
- プリプロセッサは#includeフラグを見ると、#includeを指定されたヘッダーファイルの内容に置き換えます。
- ヘッダープロテクタ:ヘッダープロテクタは、プリプロセッサ変数の状態(定義済みと未定義)に依存します。
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
struct Sales_data{
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
#endif