C++レビューのメンバー関数のリロード、クラスと構造体、thisポインタ
3118 ワード
前の記事では、インラインメンバー関数の定義には、クラス内で直接定義する方法と、クラス外で定義する方法の2つがあります.コードは次のとおりです.
1つ目の定義方法:
次に、メンバー関数のリロードについて説明します.
メンバー関数のリロードには条件があり、まず同じ役割ドメインを持つ必要があります.パラメータが異なり(パラメータタイプが異なり、パラメータ個数が異なり、パラメータ順序が異なる場合があります)、関数名が同じです.このようなメンバー関数がリロードを構成します.次に、リロードの例を示します.
クラスと構造体(structとclass)
Cにおける構造体structは,実際にはC++におけるclassと少し類似しており,種々のデータ構造と方法を1つの容器に閉じ込めることができる.唯一の違いは、アクセス権限が指定されていない場合、structのデフォルトはpublicであり、classのデフォルトはprivateであることです.次のようになります.
thisポインタについて
このポインタを明らかにするには、C++でメンバー関数のコードがすべてのオブジェクトに対して共有され、各オブジェクトのデータメンバー空間が独立している背景を理解する必要があります.では、各オブジェクトがメンバー関数を呼び出すとき、メンバー関数はどのオブジェクトのデータを操作すべきかをどのように区別しますか?すなわち、メンバー関数は、呼び出されたオブジェクトのデータ・メンバーが操作されることをどのように知っていますか?これは主にC++コンパイラによって行われます.C++コンパイラは、メンバー関数が呼び出されるたびに、最初のパラメータにオブジェクトのポインタを追加して、メンバー関数が操作するオブジェクトのデータを教えます.コンパイラが渡すこのポインタは見えず、隠されています.
プログラムコードでメンバー関数を呼び出すには、次のようにします.
コンパイラが処理すると、次のようになります.
1つ目の定義方法:
class Test
{
public:
void add(int a, int b) // 。
{
return a+b;
}
};
の第2の定義は、次のとおりです.inline Test::add(int a, int b) //
{
return a+b;
}
インライン関数の目的は主にプログラム実行の効率を高めることであり、コンパイラはコンパイル時にコードを呼び出しの場所に直接埋め込むことで、関数呼び出しのオーバーヘッドを低減し、インライン関数を使わずにコードを直接埋め込むと、コードボリュームが増大し、実際には空間で時間を交換する戦略である.したがって、インライン関数のコードは短くなければならない.インライン関数はコンパイラにとって単なるヒントであり、また、関数にswitch forなどの文が含まれている場合、コンパイラはそれをインラインと解読しない.次に、メンバー関数のリロードについて説明します.
メンバー関数のリロードには条件があり、まず同じ役割ドメインを持つ必要があります.パラメータが異なり(パラメータタイプが異なり、パラメータ個数が異なり、パラメータ順序が異なる場合があります)、関数名が同じです.このようなメンバー関数がリロードを構成します.次に、リロードの例を示します.
class Test
{
public:
void Init();
void Init(int x);
void Init(int x, int y);
void Init(int x, int y, int z);
//void Init(int x=0, int y= 0, int z= 0 ); // void Init(); ,
};
上記の例では、複数のInit関数が定義されており、それらのパラメータが異なるため、リロードが構成されているが、メンバー関数のリロードは、上記のコードの注釈行のようなデフォルト値のパラメータを持つメンバー関数のリロードに対して二義性を回避する必要があることに注意しなければならない.パラメータを持たないメンバー関数Init()と2つの意味があり、コンパイラでは区別できないため、エラーが発生します.クラスと構造体(structとclass)
Cにおける構造体structは,実際にはC++におけるclassと少し類似しており,種々のデータ構造と方法を1つの容器に閉じ込めることができる.唯一の違いは、アクセス権限が指定されていない場合、structのデフォルトはpublicであり、classのデフォルトはprivateであることです.次のようになります.
class Test
{
int x; //actually x is private.
};
struct Test
{
int x; //x is public
};
はclassで関数を定義できますが、C++のstructでも関数を定義できます.ただし、アクセス権はpublicです.classで定義されているすべてのデータメンバーとメンバー関数がpublicである場合、struct定義とは何の違いもありません.次のコードは非常に簡単で、両者の違いがわかります.struct Test2
{
int x_;
int y_;
int z_;
void Init(int x, int y, int z)
{
x_ = x;
y_ = y;
z_ = z;
}
};
class Test3
{
int x_;
int y_;
int z_;
void Init(int x, int y, int z )
{
x_ = x;
y_ = y;
z_ = z;
}
};
int main()
{
Test2 t; // C++ ,struct , struct
t.Init(10,20,30);
Test2 t2 = {10,20,30}; //C ,
Test3 t3;
t3.Init(10,20,30);//Error,Init t3 private ,
Test3 t4 = {10,20,30}; //Error, class , private, struct 。
}
thisポインタについて
このポインタを明らかにするには、C++でメンバー関数のコードがすべてのオブジェクトに対して共有され、各オブジェクトのデータメンバー空間が独立している背景を理解する必要があります.では、各オブジェクトがメンバー関数を呼び出すとき、メンバー関数はどのオブジェクトのデータを操作すべきかをどのように区別しますか?すなわち、メンバー関数は、呼び出されたオブジェクトのデータ・メンバーが操作されることをどのように知っていますか?これは主にC++コンパイラによって行われます.C++コンパイラは、メンバー関数が呼び出されるたびに、最初のパラメータにオブジェクトのポインタを追加して、メンバー関数が操作するオブジェクトのデータを教えます.コンパイラが渡すこのポインタは見えず、隠されています.
プログラムコードでメンバー関数を呼び出すには、次のようにします.
Test t1;
t1.Init(10,20,30);
コンパイラが処理すると、次のようになります.
Test t1;
t1.Init(&t1, 10, 20, 30);
このコンパイラによって渡されたポインタはthisポインタであり、メンバー関数コードが実行されるとt 1のデータメンバーを指す.もちろん、このthisポインタはメンバー関数定義時に省略できます.