const int*pとint*const pの違いとconstの他の使い方

3543 ワード

const int*pでconst修飾は*p
int*const pでconst修飾はp
ポイントはconstが何を修飾しているかを見ることです
テクニックはconstと*の相対的な位置を見ることです
constが*の左側にある場合、ポインタが指す値は変更できません.constが*右側にある場合、ポインタ自体は変更できません.
例:
const int*pOne(推奨)またはint const*pOne;//整形定数のポインタを指し、その値は変更できません
int * const pTwo;//整形を指す定数ポインタ.他の変数を指すことはできませんが、(変数)を指す値は変更できます. 
const int*const pThree(推奨)またはint const*const pThree;//整形定数を指す定数ポインタ.他の定数を指すことも、値を変更することもできません.
上記の2つ目の方法で変更できないポインタを定義したい場合は、次の形式でなければなりません.
int*const p=アドレス;(ポインタ自体の値は変更できないので初期化する必要があります)
==================================================
ブログパークhttps://www.cnblogs.com/xkfz007/articles/2419540.html
次にconstの他の使い方を説明します.
const修飾関数パラメータ
const修飾関数パラメータは、関数体でパラメータの値(パラメータ自体の値またはパラメータに含まれる値を含む)を変更できないことを示す最も広範な用途です.
void function(const int Var);     //                (   ,           )

void function(const char* Var);   //              

void function(char* const Var);   //            (    ,var              )

void function(const Class& Var); //             

パラメータconstは通常、パラメータがポインタまたは参照の場合に使用されます.入力パラメータが「値伝達」方式を採用すると、関数がパラメータをコピーするために自動的に一時変数を生成するため、このパラメータは保護する必要がないので、const修飾は必要ありません.
const修飾クラスオブジェクト/オブジェクトポインタ/オブジェクトリファレンス
const修飾クラスオブジェクトは、オブジェクトが定数オブジェクトであることを示し、メンバーは変更できません.オブジェクトポインタとオブジェクトリファレンスについても同様です.
const修飾オブジェクト.このオブジェクトの非constメンバー関数は呼び出されません.なぜなら、非constメンバー関数にはメンバー変数を変更しようとする企みがあるからです.
例:
class AAA

{    
    void func1();

    void func2() const;

}

const AAA aObj; //aObj  const     ,  aObj        const  

aObj.func1();   

aObj.func2();   

 

const AAA* aObj = new AAA();  //aObj  const       ,  aObj         const  


aObj->func1();   
aObj->func2();   

const修飾データメンバー
constデータメンバーは、あるオブジェクトの生存期間内にのみ定数であり、クラス全体に対して可変である.クラスは複数のオブジェクトを作成できるため、constデータメンバーの値が異なるオブジェクトもあります.クラス宣言でconstデータメンバーを初期化することはできません.クラスのオブジェクトが作成されていない場合、コンパイラはconstデータメンバーの値が何なのか分かりません.たとえば、次のようにします.
class A
{
    const int size = 100; //  
    int array[size];       //  ,   size
}

constデータメンバーの初期化はクラスの構造関数の初期化リストでのみ行うことができます.クラス全体で一定の定数を設定するには、クラス内の列挙定数を使用します.たとえば、次のようにします.
class A
{

…
  enum {size1=100, size2 = 200 };
  int array1[size1];
  int array2[size2];
…

}

列挙定数はオブジェクトのストレージ領域を占有せず、コンパイル時にすべて評価されます.ただし、列挙定数の隠しデータ型は整数であり、その最大値は限られており、浮動小数点数を表すことはできません.
const修飾メンバー関数
const修飾クラスのメンバー関数は、const修飾メンバー関数ではオブジェクトのメンバー変数を変更できません.一般的にconstはメンバー関数の最後に書きます.
class A

{
...

void function()const; //     ,            (   mutable  ).           const    。

...

} 

constクラスオブジェクト/ポインタ/参照の場合、クラスのconstメンバー関数のみが呼び出されます. 
const修飾メンバー関数の戻り値
1、一般的に、関数の戻り値がオブジェクトの場合、constと宣言した場合、オペレータの再ロードに使用されることが多い.通常、const修飾関数の戻り値タイプがオブジェクトまたはオブジェクトへの参照である場合は推奨されません.理由は次のとおりです.constオブジェクトを返すか、constオブジェクトの参照を返すと、戻り値にはconstプロパティがあり、戻りインスタンスはクラスAの共有(保護)データメンバーとconstメンバー関数にのみアクセスでき、割り当て操作は許可されません.これは一般的にはあまり使用されません.
2、「ポインタ伝達」方式の関数戻り値にconst修飾を加えると、関数戻り値(すなわちポインタが指す内容)は変更されず、この戻り値はconst修飾を加える同型ポインタにしか与えられない.
const char * GetString(void);

//            :
char *str=GetString();

//       :
const char *str=GetString();

const定数とdefineマクロ定義の違い
(1)コンパイラの扱い方が異なる
defineマクロは、前処理フェーズで展開されます.
const定数はコンパイル実行フェーズで使用されます.
(2)タイプとセキュリティチェックが異なる
defineマクロにはタイプがなく、タイプチェックを行わず、展開するだけです.
const定数には特定のタイプがあり、コンパイルフェーズでタイプチェックが実行されます.
(3)記憶方式が異なる
defineマクロは展開するだけで、どこで使うか、何度展開してもメモリは割り当てられません.
const定数はメモリに割り当てられます(スタック内でもスタック内でも構いません).