私は現在、C++ と少しの Python でいくつかのクラスを受講しています。そして、よく出てくるのは、クラスを作成しているときに何が起こっているのかを本当に理解していないということです。C ++のクラスに関する限り、誰かが詳細を説明できるか、少なくとも非常に詳細なWebサイトを教えてくれるかどうか疑問に思っていました. 私は宣言を知っていますが、アクセサー、メソッド、コンストラクター、およびデストラクタで何が起こっているかについて、また、クラスを使用するのに最適な時期と理由を定義するまで行きたい場合でも。全体的な説明が必要です。ありがとう!
3 に答える
プログラミングでは、データとそのデータを操作する関数があります。構造 ( struct
) を使用すると、関連するデータを 1 つの論理オブジェクトにグループ化できます。
クラスを使用すると、データと関数を 1 つの単位としてグループ化できます。したがって、 と言う代わりに、 と言うmatrix_add(m1, m2)
ことができますm1.add(m2)
。データと関数は、(private
クラスからのみアクセス可能)、protected
(クラスとその子からアクセス可能)、またはpublic
(誰でもアクセス可能) にすることができます。これはカプセル化と呼ばれます。通常、データはプライベートであり、一連のパブリック関数を介してアクセスできます。C++ では、struct
デフォルトで a がパブリック スコープになり、aclass
がプライベート スコープになりますが、それ以外は同じです。
アクセサーは、通常、クラスのプライベート データへのアクセスを提供する関数の名前です。これらは、データを返す (または取得する)ゲッター、またはデータを変更 (または設定) するセッターです。通常、これらのメソッドは入力の有効性をチェックして、内部制約が保持されていることを確認します。アクセサーはプライベート データを直接返すのではなく、派生プロパティを返す場合があることに注意してください。つまり、size
C empty
++ コンテナー (ベクター、リストなど) では、これらが計算された値である場合でも、アクセサーと見なすことができます。
コンストラクターは、クラスがデータを適切な値に初期化できるようにする、またはユーザーが潜在的に異なるデータを使用してクラスの新しいオブジェクトを作成できるようにする特別な関数です。たとえば、四角形クラスは、別の四角形、ポイントとサイズ、上/左/下/右の値のセットから構築することも、空にすることもできます。C++ では、コンストラクターはクラスと同じ名前です。Python では、これは と呼ばれ__init__
ます。
デフォルトのコンストラクターは、パラメーターをとらず、クラスをデフォルトの状態に初期化するコンストラクターです (たとえば、行列クラスの恒等行列)。
コピー コンストラクターは、クラス型の別のオブジェクトを受け取り、そのコピーを作成するコンストラクターです。これにより、割り当てられたメモリを適切に処理できます (文字列やベクトル クラスなど)。単純なデータ構造では、オブジェクトは値によってコピーされるため、2 つのオブジェクトは同じメモリを参照します。
デストラクタは、クラスがクリーンアップを実行できるようにする特別な関数です。これには、割り当てられたメモリの削除、ミューテックスのロックの解放、開いているファイル ハンドルのクローズなどがあります。C++ では、デストラクタはクラスと同じ名前ですが、その~
前に が付きます。たとえば、matrix
クラスの場合、デストラクタは~matrix
.
メソッドは、クラスの一部である単なる関数です。各メソッドは、操作対象のクラス オブジェクトを最初のパラメーターとして受け取ります。メソッドを宣言するとき、C++ はこれを内部的に行います (暗黙のthis
引数を提供します) が、Python はパラメーターを明示的に提供する必要があります。
C++ では、演算子+
は、 、-
、*
などを実装するために使用される特別な関数です/
。これにより、組み込み型のように使用できるクラスを作成できます (特に、ベクトル、行列、複素数、有理数などの数学クラス)。
クラス (「派生」クラス) は、別のクラス (「基本」クラス) から継承できます。ここで、派生クラスは基本クラスの子であり、任意のprotected
データまたはメソッドにアクセスできます。これは継承と呼ばれます。これらはクラス階層を形成します。
virtual
クラスは、派生クラスによってオーバーライドできるメソッドを持つように構築できます。これはポリモーフィズムと呼ばれます。
実装を提供しない仮想メソッドを宣言できます。これらのメソッドは純粋仮想メソッドと呼ばれ、それらを提供するクラスは抽象基底クラスと呼ばれます。ここで、派生クラスはこれらのメソッドを実装する必要がありますが、非純粋仮想メソッドの場合、派生クラスはメソッドを実装する必要はありません。
純粋仮想メソッドのみを持つ (他のメソッドを持たない) クラスは、実質的にインターフェイスクラスです。C++ にはこれに関する特別な表記法はありませんが、他の言語にはあります。
インターフェイスは通常、2 つ以上の異なるシステム間で対話するために使用されます。たとえば、音楽プレーヤーは、プラグインが処理できるサポートされているオーディオ形式を拡張できるようにするプラグイン アーキテクチャを提供できます。ここで、インターフェースはプレーヤーとプラグインの間の契約を提供します。
オブジェクトは、データだけでなく、そのデータを操作するためのコードも含む「スマート」な構造と考えてください。クラスは、これらの「スマート」構造の型定義と考えてください。
クラスインスタンスの作成は、構造型の変数の作成と同じです。クラスのメンバー関数を呼び出すことは、通常の関数を呼び出し、その構造を「this」という名前のパラメーターとしてクラスに渡すことと同じです。
これを理解したとき、あなたはすでにオブジェクト指向プログラミングが何であるかについて最も理解しています。
ちなみに、キーワードstruct
とclass
C ++の違いは何ですか?構造体では、すべてのメンバーがデフォルトでパブリックであり、クラスでは、すべてのメンバーがデフォルトでプライベートです。それでおしまい。それ以外の点では、構造体とクラスは同じものです。すべてのメンバーをプライベート、パブリック、または保護として明示的に宣言すると、それらを切り替えることができ、プログラムは以前と同じようにコンパイルおよび動作します。
そして、よくあることは、クラスを作成しているときに何が起こっているのかを本当に理解できないことです。
他の人が2番目の部分に答えたので、私はこの部分に答えています。以下のコードはJavaですが、コードを見ると、Java構造よりもクラスの概念が重要になります。
さて、プログラミングの世界でCLASSに飛び込む前に。現実の世界を見てみましょう。私たちの周りを見ると、私たちの生きているエコーシステムに多くの要素[岩、動物、人間、植物など]があります。注意深く観察すると、それらにはグループ化できるいくつかの共通の機能があることがわかります[生命、臓器、色など]。この共通のグループ化を「クラス」と呼ばれる技術名で呼びましょう。
理解するために、プログラミングの世界のクラスは、なぜクラスと呼ばれるそのような構造があるのかを理解する必要があります。主な事実は、それがオブジェクト指向プログラミングと呼ばれるプログラミングパラダイムの一部であり、プログラマーが実世界のオブジェクト(車両、銀行など)をオブジェクトと呼ばれるプログラミングモデルにマッピングしようとすることです。これらのオブジェクトを作成するには、これらのオブジェクトを実際に記述できる構造を作成する必要があります。このような構成はクラスと呼ばれます。
以下の説明は、完全を期すためにクラスだけにとどまりません。
円、長方形、正方形、六角形の技術的な例を見てみましょう。それらを見ると、SHAPEと呼ばれる一般的なクラスに属していることがわかります。
以下の例の詳細[extends、@Overrideなど]に夢中にならないでください。これは、新しいクラスを作成するためにどのように活用されるかを分類するという単純な概念を説明しています。クラスが作成されると、それは単なるスケルトンになります。つまり、実際に使用するためのメモリは割り当てられません。クラスを便利にするために、そのオブジェクトを作成します。したがって、オブジェクトは、同じクラスに対して異なる状態を持つ「要素」です。
円オブジェクトobj1、obj2の場合、各オブジェクトの半径は異なります。
class Shape {
String name;
int color;
public Shape(String name, int color) {
this.name = name;
this.color = color;
}
String getName() {
return name;
}
int getColor() {
return color;
}
double getArea() {
return 0;
}
double getPerimeter() {
return 0;
}
}
class Rectangle extends Shape {
int l, b;
public Rectangle(int l, int b, int h, int color) {
super("Rectangle", color);
this.l = l;
this.b = b;
}
/* Overloading */
@Override
double getArea() {
return l*b;
}
/* Overloading */
@Override
double getPerimeter() {
return (2*l + 2*b);
}
}
class Circle extends Shape {
int r;
public Circle(int r, int color) {
super("Circle", color);
this.r = r;
}
dobule getArea() {
return (PI * (r*r));
}
double getPerimeter() {
return (2*PI*r);
}
}