目次
1. クラスとオブジェクトの初期理解
1.1 プロセス指向とオブジェクト指向の違い
C 言語はプロセス指向であり、プロセスに焦点を当て、問題を解決するためのステップを分析し、関数呼び出しを通じて問題を段階的に解決します。C++ はオブジェクト指向に基づいており、オブジェクトに焦点を当て、1 つのものをさまざまなオブジェクトに分割し、オブジェクト間の相互作用に依存して完了します。
簡単な例を挙げてみましょう。
シンプルなテイクアウト システムの設計は
プロセス指向であり、注文、注文の受け取り、食事の配達のプロセスを実現することに重点を置いています。コード レベルで反映される - メソッド/関数
オブジェクト指向:クラス オブジェクトの実装と、クラス オブジェクト、ユーザー、マーチャント、ライダー間の関係、およびそれらの間の関係に焦点を当てます。コードレベルでの反映 - クラス設計とクラス間の関係
1.2 クラスの紹介
C 言語では、ストラクチャのカスタム タイプをすでに学習しました。ストラクチャを使用して学生タイプを定義しましょう。
struct Student
{
char name[10];
int age;
int id;
};
int main()
{
struct Student s1; //兼容C
Student s2; //升级到类,Student为类名,也是类型
return 0;
}
C++ は C 構文と互換性があるため、structも C++ のクラスにアップグレードされます。C 言語では、構造体変数を定義した後にメンバー変数を初期化することはできませんが、C++ では、構造体内でメンバー関数を定義し、同時にメンバー変数を初期化することができます。メンバー関数を使用して、構造体変数やその他の操作を初期化できます。どのように機能するかを見てみましょう。
struct Student
{
//成员变量
char _name[10];
int _age;
int _id;//前面加_是为了和后面函数的形参进行区分
//成员方法
//初始化成员变量
void Init(const char* name, int age, int id)
{
strcpy(_name, name);
_age = age;
_id = id;
}
//打印成员变量
void Print()
{
cout << _name << endl;
cout << _age << endl;
cout << _id << endl;
}
};
int main()
{
struct Student s1; //兼容C
Student s2; //升级到类,Student为类名,也是类型
s1.Init("张三", 18, 1);
s2.Init("李四", 19, 2);
s1.Print();
s2.Print();
return 0;
}
印刷結果:
1.3 内の定義
class はクラスを定義するためのキーワードです。
class className
{
//类体:由成员变量和成员函数组成
};
では、上記の構造体コードのキーワード「struct」を「class」に変更することはできるのでしょうか?試してみてください:
明らかに、コンパイラはエラーを報告しました。心配しないでください。以下にエラーの理由を 1 つずつ紹介します。
まず、オブジェクト指向には、カプセル化、継承、ポリモーフィズムという 3 つの大きな特徴があります。
最初に理解する必要があるのはカプセル化です。
1. オブジェクト指向ではデータとメソッドをクラスにまとめる
2. C++ はアクセス修飾子を通じてカプセル化を実装します。
アクセス修飾子は次のとおりです
1.4 クラスアクセス修飾子とカプセル化
1.4.1 アクセス修飾子
C++ でカプセル化を実現する方法:クラスを使用してオブジェクトのプロパティとメソッドを組み合わせてオブジェクトをより完璧にし、アクセス権を通じてそのインターフェイスを外部ユーザーに選択的に提供します。
アクセス修飾子の説明:
1.パブリックに変更されたメンバーは、クラスの外部から直接アクセスできます。
2.プロテクトおよびプライベートの変更されたメンバーは、クラスの外部から直接アクセスできません(ここでは、プロテクトとプライベートは類似しています)
3. アクセス権の範囲は、このアクセス修飾子から現れます。次のアクセス修飾子が表示されます。
4. 後ろにアクセス修飾子がない場合、スコープはクラスの最後で終了します。
5.クラスのデフォルトのアクセス権は private (struct は C と互換性があるため struct public)
5 番目のポイントは、クラスのデフォルトのアクセス権がプライベートであるため、上記のコード コンパイラーはエラーを報告します。メンバー関数をパブリックに設定した場合 (またはメンバー変数とメンバー関数の両方をパブリックに設定した場合)、コンパイラはエラーを報告しません:
したがって、クラスを定義するときは、class/struct のデフォルトの修飾子を使用するのではなく、アクセス修飾子を明確に定義するようにしてください。そうすることで、他の人がコードを読んだときにメンバーの属性が一目でわかるようになります。
1.4.2 梱包
カプセル化は厳密な管理の一種であり、非カプセル化は自由な管理の一種です。
C++ では、データとメソッドはクラスにカプセル化され、アクセスできるメンバーはパブリックとして定義され、アクセスしたくないメンバーはプライベートとして定義されます。
カプセル化を使用する利点:
1. コードを呼び出すプログラム フラグメントを変更せずに、独自のコードを変更できるため、コードの保守が容易になります。
2. 関連する変数と関数をオブジェクトにカプセル化します。変数はオブジェクトのプロパティを記述し、関数はオブジェクトの動作を記述します。これは、客観的な世界の理解と一致しています。
3. 属性に対するデータアクセス制限も実装し、プログラムコードのセキュリティも強化します。
1.5 クラスの範囲
クラスは新しいスコープを定義し、クラスのすべてのメンバーはクラスのスコープ内にあります。クラス外のメンバーを定義するには、::スコープ パーサーを使用して、メンバーがどのクラス ドメインに属しているかを示す必要があります。
モジュール型プログラミングの実際の開発での使用:
Stack.h ファイル:
#pragma once
class Stack
{
public:
void Init();
void Push(int x);
// ...
//private:
int* _a;
int _top;
int _capacity;
};
Stack.cpp ファイル:
#include "Stack.h"
void Stack::Init()
{
_a = nullptr;
_top = _capacity = 0;
}
これにより、データとメソッドの分離が実現します。
1.6 クラスオブジェクトモデル
1.6.1 クラスオブジェクトのサイズの計算方法
1. クラスサイズの計算は構造調整原則に従います
2. クラスのサイズはデータ メンバーに関連しており、メンバー関数とは関係ありません (空のクラスのサイズは 1 バイトです)。クラスのサイズは静的データ メンバーとは関係ありません。
3. 空のクラスは 1 バイトを与えます。このバイトには有効なデータは格納されません。オブジェクトが存在することを示すために場所を占有するだけです。
ケース 1: クラス内にメンバー変数とメンバー関数の両方が存在する
class A1
{
public:
void f1() {}
private:
int _a;
};
サイズ: 4バイト
ケース 2: クラス内にメンバー関数のみがある
class A2
{
public:
void f1() {}
};
サイズ: 1バイト
ケース 3: クラスに何もない
class A3
{
};
サイズ: 1バイト