5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++ メモ:変数

Last updated at Posted at 2015-10-16

前書き

主に自分用。まァ役に立てればなによりですが。

内容

参照

参照とポインタ

参照はオブジェクトではないので、参照へのポインタは定義できません。

int num, &ref = num, &*ptrToRef = &ref; // エラー

ポインタはオブジェクトなので、ポインタへの参照は定義できます。

int num, *ptr = &num, *&refToPtr = ptr; // OK

const

extern について

複数のファイルに亘って同じ定数を使う場合は、個々のファイルにそれぞれ定義を書きます。

source0.cpp
const int alpha = 12;
int beta = alpha * 2;
source1.cpp
const int alpha = 12;
int gamma = alpha / 3;

一つのファイルだけに定数の定義を書き、他のファイルには宣言だけ書くこともできます。externを使うのですが、宣言だけでなく、定義にも使います。

source0.cpp
extern const int alpha = 12;
int beta = alpha * 2;
source1.cpp
extern const int alpha;
int gamma = alpha / 3;

const への参照

const への参照で変数への参照を初期化することはできません。

int var = 7;
const int con = 8;
const int &ref0 = con;
int &ref1 = con; // エラー

型さえ合っていれば、何ででも const への参照を初期化することができます。

int a = 0;
const int &ref0 = 0;
const int &ref1 = a;
const int &ref2 = a + 1;

const なポインタと const を指すポインタ

const が来る位置で色々決まります。

int i = 0;
const int *a = &i;       // const を指すポインタ (所謂 low-level const)
int *const b = &i;       // const なポインタ (所謂 top-level const)
const int *const c = &i; // const を指す const なポインタ

top-level const とはそのオブジェクト自体const であることを意味します。だから、top-level const を持つオブジェクトの値を変えることは出来ません。

low-level const とはそのポインタが指すオブジェクト、またはその参照が指すオブジェクトが const であることを意味します。

constexpr

constexpr で宣言されたオブジェクトは返り値の変わらない式で初期化されなければいけません。constexpr で宣言されたオブジェクトは top-level const になります。

constexpr int *ptr0 = nullptr;       // const なポインタ
constexpr const int *ptr1 = nullptr; // const を指す const なポインタ

typedef

typedef を使って長い型指定子を好きな型指定子に名前を変えることができます。

typedef double dd, *dptr, &dref;
dd pi = 3.14;                    // pi は double
dptr piptr = π                // piptr は double を指すポインタ
dref piref = pi;                 // piref は double への参照

C++11 では using を使って似たようなことができます。

using dd = double;              // double
using dptr = double*;           // double を指すポインタ
using dref = double&;           // double への参照

typedef した型指定子の前に const を付けると top-level const となります。

typedef double dd, *dptr;
dd a = 0;
const dptr p = &a;        // double を指す const なポインタ

auto

auto を使った宣言で、初期化子が参照だと、型指定子は参照が指すオブジェクトの型となります。参照にしたい場合、識別子の前に & を書きます。

int a = 0, &r = a;
auto n = r;        // int
auto &n = r;       // int への参照

また、auto を使うと、初期化子の top-level const がなくなります。low-level const は残ります。top-level const にしたい場合は、const auto と書きます。

const int c = 0, &r = c; // top-level const な c と low-level const な参照 r
auto d = c;              // int (top-level const がなくなった)
auto e = r;              // int (参照から const int へ変わり、top-level const がなくなった)
auto f = &c;             // const int を指すポインタ (&c は low-level const なので)
const auto g = c;        // const int (const auto による top-level const 指定)

decltype

decltype は top-level const も参照もそのまま型指定子となります。

const int a, &ref = a;
decltype(a) i = 12;    // const int
decltype(ref) r = a;   // const int への参照

左辺値も左辺値のままだったり。

int a, *ptr = &a;
decltype(*ptr) ref = a; // *ptr は int ではなく int への参照 (左辺値)

decltype に通す変数名に括弧を付けると、それは式として評価されます。括弧を付けなければ、単純に変数として通されます。式として評価されると、変数は参照に変わります。

int a = 9, &r = a;
decltype((a)) ref = a; // int への参照
decltype(a) num = 0;   // int
decltype(r) rref = a;  // int への参照 (r がもともと参照なので)
5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?