banner
cells

cells

为美好的世界献上 code

ポインタ定数と定数ポインタについて

ポインタ定数#

int *const ptr = nullptr;

const はポインタ ptr の値を修飾しており、ptr 自体は変更できないため、ポインタ定数は初期化する必要があります。また、ptr の値を変更することはできません。

int a = 10;
int *const ptr = &a;
ptr = nullptr; // エラー

ポインタ定数の使用例#

例えば、2 つの整数の値をポインタを介して交換する関数を作成する必要があるとします。

以下は実装コードです:

void swap(int *a, int *b) {
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

上記のコードは機能を実現できますが、問題があります。関数内でポインタの指す値を変更したり、ポインタの値を変更したりできるため、コードが強固ではありません。コードをより堅牢にするために、ポインタ定数を使用することができます。

以下は修正後のコードです:

void swap(int *const a, int *const b) { ... }

定数ポインタ#

const int *ptr;
// または
int const *ptr;

const*ptr の値、つまりポインタが指す値を修飾しており、ptr が指す値は変更できません。また、定数型変換を行わない限り、*ptr を変更することはできません。

int a = 10;
int const *ptr = &a;
*ptr = 20; // エラー

定数ポインタの使用例#

例えば、配列を出力する関数を作成する必要があるとします。

以下は実装コードです:

void printArray(int const* arr, size_t len) {
    for (size_t i = 0; i < len; ++i) {
        std::cout << arr[i] << " ";
    }
}

ここで、配列から退化したポインタの値を const 修飾するだけで十分だと思うかもしれませんが、まだ問題があります。関数内でポインタの値を変更することができるため、これは望ましくありません。したがって、ポインタの値にも const を修飾する必要があります。

以下は修正後のコードです:

void printArray(int const *const arr, size_t len) { ... }

ポインタ定数と定数ポインタの関係#

定数ポインタには 2 つの書き方があることに気づくでしょう:int const *const int *

最初の形式の理解について:const左側を修飾するものであり、例えば int const *ptr; では const は値の型 int を修飾しているため、ポインタが指す値を変更できません。int *const ptr = nullptr; では constint * ポインタ型を修飾しているため、ポインタが指す先を変更できません。この理解はコードの規約に従う必要があります。なぜなら、定数ポインタを const int * のように書くと変換が必要になるからです。(または、左側にオブジェクトがない場合、右側のオブジェクトを修飾すると解釈することもできます。)

定数ポインタポインタ定数の命名は const int *int *const のコード規約に対応しています。

以下のコードを見てみましょう:

#include <iostream>

struct A {
    void foo() { std::cout << "non const" << std::endl; }
    void foo() const { std::cout << "const" << std::endl; }
};

int main() {
    A a;
    A *const ptr1 = &a;
    ptr1->foo();
    A const *ptr2 = &a;
    ptr2->foo();
}

int *const ptr1 = &a では constptr1 ポインタの値を修飾しており、ポインタが指すオブジェクトを修飾していません。そのため、ptr1->foo() は非 const バージョンを呼び出します。

int const *ptr2 = &a では constptr2 ポインタが指す値 a を修飾しており、指す値を変更できないことを意味します。そのため、ptr2->foo()const バージョンを呼び出します。

もし間違いがあれば、指摘してください。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。